Fix the Exception “Cannot issue data manipulation statements with executeQuery()”
1. 서론
이 튜토리얼에서는 예외 Cannot issue data manipulation statements with executeQuery(). 을 해결하는 방법을 살펴보겠습니다.
데이터베이스와 상호작용하기 위해 JDBC를 사용할 때 이 문제를 겪는 것은 흔하지 않지만, 다행히도 쉽게 해결할 수 있습니다.
2. 예외 이해하기
예외 메시지 자체가 오류가 발생할 수 있는 위치를 알려주지만, 문제의 깊이를 살펴보겠습니다.
2.1. 그것은 무엇을 의미하나요?
예외 Cannot issue data manipulation statements with executeQuery()는 코드가 executeQuery() 메소드를 사용하여 INSERT, UPDATE 또는 DELETE 문을 실행하려고 할 때 발생합니다.
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¨NBSP;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 문 유형에 맞는 올바른 메소드를 사용해야 합니다.
이전에 논의했던 예제를 재검토하여, INSERT 문을 executeQuery() 메소드로 실행하려고 했던 것을 보여드리겠습니다. 이번에는 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"));
}
다음은 사용 가능한 메소드와 그 목적에 대한 간단한 개요입니다:
메소드 | 목적 |
---|---|
executeQuery() | 데이터베이스에서 데이터를 검색하기 위해 SELECT 문을 실행하는 데 사용됩니다. |
executeUpdate() | INSERT, UPDATE, DELETE와 같은 DML 문 및 CREATE, ALTER와 같은 DDL 문을 실행하는 데 사용됩니다. |
execute() | 사전 결정된 유형이 없는 경우, 일반적으로 SQL 문을 실행하는 데 사용됩니다. |
4. 결론
이 기사에서는 비교적 드문 오류인 Cannot issue data manipulation statements with executeQuery() 를 조사하고 그 원인을 이해했습니다. 특정 SQL 문에 대해 올바른 JDBC 메소드를 사용하는 것의 중요성도 배웠습니다. 각각의 메소드는 고유한 목적을 가지고 있습니다.
전체 코드 예제는 GitHub에서 사용할 수 있습니다.