가장 큰 차이점은 캐시(cache) 사용여부이다.
Statement를 사용하면 매번 쿼리를 수행할 때마다 다음과 같은 과정을 거친다.
쿼리 문장 분석 -> 컴파일 -> 실행
반면에, PreparedStatement는 처음 한 번만 세 단계를 거친 후 캐시에 담아 재사용한다.
만약 반복적으로 수행한다면 PreparedStatement를 사용하는 게 DB에 부담이 훨씬 적을 것이다.
참고 : TEST 테이블의 USER_NO컬럼은 NUMBER타입, USER_NAME컬럼은 VARCHAR2 타입이다.
...
String sql = "SELECT * FROM TEST WHERE USER_NO="+userNo+" AND USER_NAME='" + userName+"'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
...
...
String sql = "SELECT * FROM TEST WHERE USER_NO=? AND USER_NAME=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 3);
pstmt.setString(2, "홍길동");
ResultSet rs = pstmt.executeQuery();
...
PreparedStatement는 위치홀더(?) 를 사용한다.
해당 위치에 값을 넣어주는 것이다.
import java.sql.*;
public class Pps {
public static void main(String[] args) {
int result = 0; // 결과(처리행 수)를 받아놓을 변수
Connection conn = null; // DB에 연결정보를 보관할 객체
PreparedStatement pstmt = null;
String sql = "INSERT INTO TEST VALUES(?, ?, SYSDATE)";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("JDBC Driver 등록 성공");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 2);
pstmt.setString(2, "고드름");
result = pstmt.executeUpdate(); // 처리된 행의 수 반환. insert니까 executeUpdate
if (result > 0) {
conn.commit();
}
else {
conn.rollback();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 7) 사용한 자원 반납 - 생성 역순
try {
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC Driver 등록 성공
setInt()나 setString처럼 타입에 맞는 메서드를 사용해야 한다.