Web/Java
Statement vs PreparedStatement
돌건
2021. 10. 11. 22:59
Statement와 PreparedStatement는 JDBC를 통해 SQL를 실행하기 위해서 사용되는 객체이다.
PreparedStatement와 Statement의 가장 큰 차이는 캐시를 사용하느냐에 있다. 이 두 객체는 SQL을 실행할 때 3단계를 거치게 된다.
1) SQL 문장 분석
- 문법 검사
- 의미 검사
- 권한 검사
2) 컴파일
3) 실행
Statement를 사용하는 경우, SQL을 실행할 때마다 1 ~ 3단계를 모두 거치게 된다. 반면에, PreparedStatement를 사용하는 경우에는 처음 실행하는 경우에만 3단계를 거치고 캐시에 올려둔다. 이후에는 캐시에 올라가 있는 것을 재사용하게 된다.
Statement
Connection connection = DBConnection.getConnection();
String query = "SELECT name FROM member WHERE id = " + param;
Statement stmt = connection.createStatement();
ResultSet result = stmt.executeQuery(query);
- 실행될 SQL을 한 눈에 파악할 수 있다는 장점이 있다.
- SQL을 실행할 때마다 위에서 언급한 3단계의 과정을 모두 거치기 때문에 성능상 이슈가 존재한다.
- 파라미터 바인딩 시, SQL Injection 공격에 취약하다. (위 예시에서 param의 값으로 id' or '1'='1 가 온다면 member 테이블의 모든 사용자의 데이터를 조회할 수 있다.)
PreparedStatement
Connection connection = DBConnection.getConnection();
String query = "SELECT name FROM MEMBER where id = ?"
// 1. PreparedStatement 생성
PreparedStatement pstmt = connection.preparedStatement(query);
// 2. 파라미터 바인딩
pstmt.setString(1, userId);
// 3. 쿼리 실행
ResultSet result = pstmt.executeQuery();
- 해석하면 준비된 Statement이다. 여기서 말하는 준비란 컴파일이다. 컴파일이 되어 있기 때문에 SQL을 실행할 때마다 컴파일을 할 필요가 없다. 즉, 재사용이 된다.
- placeholder를 이용해 SQL 문장에 인수가 위치할 곳을 명시한다. placeholder는 '?'로 표현한다.
- 파라미터 부분을 set메서드로 설정하기 때문에, 외부의 입력이 query문의 구조를 변경하는 것을 방지할 수 있다.