解决 JDBC 异常 “Cannot issue data manipulation statements with executeQuery()”
1、简介
本文将带你了解如何解决 JDBC 异常:“Cannot issue data manipulation statements with executeQuery()”。
在使用 JDBC 与数据库交互时,这个异常并不常见,但这个问题很容易解决。
2、理解异常
2.1、导致这个异常的原因
当我们尝试使用 executeQuery()
方法执行 INSERT
、UPDATE
或 DELETE
语句时,就会出现错误 “Cannot issue data manipulation statements with executeQuery()” 异常。
Statement
或 PreparedStatement
对象中的 executeQuery()
方法专门用于处理 SELECT
查询。如果检查一下该方法的签名,就会发现它返回的是 ResultSet
实例,其中包含从数据库中获取的记录。
使用 Connector/J 连接 MySQL 时会出现这种异常,但其他数据库也执行相同的规则。在这种情况下,它们会以不同的错误信息抛出类似的错误。
需要注意的是,在较新版本的 MySQL Connector/J 中,该错误信息已略有更新。现在是这样:
java.sql.SQLException: Statement.executeQuery() cannot issue statements that do not produce result sets.
2.2、导致该异常的场景
来看一个代码示例,以便更好地理解是什么触发了异常。如前所述,我们使用 MySQL 数据库。
首先,为示例创建一个简单的数据表:
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
email VARCHAR(50)
)
现在我们可以尝试执行一个非 SELECT
语句的查询。
在测试中执行一个简单的 INSERT
语句,并确认是否会抛出异常:
@Test
void givenInsertSql_whenExecuteQuery_thenAssertSqlExceptionThrown() throws SQLException {
String insertSql = "INSERT INTO users (username, email) VALUES (?, ?)";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.setString(1, USERNAME);
insertStatement.setString(2, EMAIl);
SQLException exception = assertThrows(SQLException.class, insertStatement::executeQuery);
assertEquals("Statement.executeQuery() cannot issue statements that do not produce result sets.", exception.getMessage());
}
3、解决问题
解决这种异常的方法很简单:必须针对要执行的 SQL 语句类型使用正确的方法。
这次,我们使用 executeUpdate()
方法来纠正上例中的做法。之后,查询数据库,以确认数据已被正确持久化。
测试修正后的代码:
@Test
void givenInsertSql_whenExecuteUpdate_thenAssertUserSaved() throws SQLException {
String insertSql = "INSERT INTO users (username, email) VALUES (?, ?)";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.setString(1, USERNAME);
insertStatement.setString(2, EMAIl);
insertStatement.executeUpdate();
String selectSql = "SELECT * FROM users WHERE username = ?";
PreparedStatement selectStatement = connection.prepareStatement(selectSql);
selectStatement.setString(1, USERNAME);
ResultSet resultSet = selectStatement.executeQuery();
resultSet.next();
assertEquals(USERNAME, resultSet.getString("username"));
assertEquals(EMAIl, resultSet.getString("email"));
}
以下是 JDBC 各个 SQL 查询方法及其用途的简要概述:
方法 | 用途 |
---|---|
executeQuery() | 用于执行 SELECT 语句,从数据库中检索数据。 |
executeUpdate() | 用于执行 INSERT 、UPDATE 、DELETE 等 DML 语句以及 CREATE 和 ALTER 等 DDL 语句。 |
execute() | 用于执行任何 SQL 语句,通常是在未事先确定类型的情况下。 |
4、总结
本文介绍了在使用 JDBC 时出现 “Cannot issue data manipulation statements with executeQuery()” 异常的原因和解决办法,还介绍了 JDBC 每个 SQL 执行方法的区别。
Ref:https://www.baeldung.com/java-jdbc-executequery-dml-error