Databases

Statement와 PreparedStatement

진공청소ㄱl 2025. 2. 25. 15:58

Statement


Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE id = 1");

 

Statement는 JDBC에서 제공하는 가장 기본적인 쿼리 실행 방식이다. 이는 데이터베이스에 SQL 문을 전달하고 실행하는 단순한 인터페이스를 제공한다.

 

Statement를 사용할 때마다 데이터베이스는 SQL 문을 파싱하고, 컴파일하여 실행 계획을 생성한다. 이러한 과정은 매 실행마다 반복되며, 불필요한 작업이다.

 

Statement의 실행 과정은 크게 네 단계로 나눌 수 있다.

  1. SQL 문장이 데이터베이스 서버로 전송
  2. 데이터베이스 서버는 받은 SQL 문장을 파싱하여 문법적 오류를 검사
  3. 실행 계획 생성
  4. 결과 반환

즉, Statement를 이용한 쿼리 실행 방식은 캐시를 사용하지 않으며, 매번 SQL 구문을 파싱하고 실행 계획을 새로 생성한다.

 

PreparedStatement


PreparedStatement pstmt = connection.prepareStatement(
    "SELECT * FROM users WHERE id = ?"
);
pstmt.setInt(1, userId);
ResultSet rs = pstmt.executeQuery();

 

PreparedStatement는 Statement의 한계를 극복하기 위해 개발된 향상된 기능이다. 가장 큰 특징은 이미 실행한 SQL 문을 미리 컴파일하여 저장한다는 점이다.

 

이는 동일한 쿼리를 반복 실행할 때 매우 효율적으로 나타난다. PreparedStatement는 플레이스홀더(?)를 사용하여 값을 동적으로 바인딩할 수 있게 해주며, SQL 인젝션 공격을 예방하는 데도 도움이 된다.

PreparedStatement의 실행 과정은 처음 쿼리를 실행할 때에는 Statement와 동일하지만, 이미 실행한 쿼리에 대해서는 Statement와 다르게 두 단계로 나뉜다.

  1. SQL 문이 데이터베이스에 전송되어 파싱, 컴파일되고 실행 계획이 생성, 이 단계는 PreparedStatement가 처음 생성될 때 한 번만 수행
  2. 준비된 쿼리에 실제 값(파라미터)을 바인딩하고 실행, 이 단계는 동일한 PreparedStatement를 재사용할 때마다 수행

즉, PreparedStatement는 SQL 문을 미리 컴파일하여 캐시에 저장함으로써 반복 실행 시 성능을 향상시키고 바인드 변수를 통해 SQL 인젝션을 방지하는 향상된 쿼리 실행 방식이다.

 

Statement가 캐시를 사용하지 않는 이유


Statement는 쿼리를 날릴 때 바인드 변수를 사용하는게 아닌 쿼리 안에 변수를 넣어서 데이터베이스로 요청을 보내게 된다. 이에 데이터베이스가 쿼리를 수행하면서 생성된 실행계획을 라이브러리 캐시에 보관하게 되는데, 이때, 라이브러리 캐시에서 SQL을 찾기위해 사용하는 키 값이 "SQL문 그 자체" 인데, 한 부분이라도 다르다면 키 값이 달라져서 캐시된 값을 찾지 못한다.

 

반면에 PreparedStatement는 바인드 변수를 사용하여 SQL 문장의 구조는 동일하게 유지하면서 값만 변경할 수 있다. 이렇게 하면 SQL 문장의 구조가 동일하기 때문에 라이브러리 캐시에서 동일한 키 값으로 실행 계획을 찾을 수 있어 매번 새로운 파싱과 컴파일 과정을 거치지 않고 캐시된 실행 계획을 재사용할 수 있다.

 

참고

[JDBC] Statement vs. PreparedStatement

 

[JDBC] Statement vs. PreparedStatement

`Statement`는 DB에 쿼리를 보내 실행시키는 객체이다. `PreparedStatement`는 `Statement`를 상속받은 객체로, 확장된 기능을 가지고 있어 더 자주 사용되지만 `Statement`를 완전히 대체할 수 있는 것은 아니다

velog.io

 

[JDBC] Statement vs. PreparedStatement Statement 대신 preparedStatement 사용하는 이유 :: codemon

 

Statement 대신 preparedStatement 사용하는 이유

이유는 Statement 객체에서 사용한 createStatement()라는 메소드 때문입니다. 이것을 사용할 경우 사용자의 입력 값을 미리 만들어 놓은 sql문에 적용한 후 컴파일을 하기 때문에 사용자의 입력 값에 따

oper6210.tistory.com