PreparedStatement

PreparedStatement는 지금까지 사용한 Statement인터페이스보다 편리하고 효과적이다.
PreparedStatement인터페이스는 Statement인터페이스를 상속한다.
때문에 지금까지 예제에서 나왔던 메소드 몇몇은 이번 예제에서도 그대로 쓰인다.

Statement가 DBMS에 전달하는 SQL문은 단순한 문자열이다.
DBMS는 이 문자열을 DBMS가 이해할 수 있도록 컴파일하고 실행한다.
반면 PreparedStatement는 컴파일된 SQL문을 DBMS에 전달하여 성능을 향상시킨다.
성능이 향상될 뿐 아니라 편리한 점도 있다.
SQL문에 ?을 넣을 수 있고, ?부분의 값을 설정할 수 있다.
그러므로써 동일한 SQL문을 ?에 값만 바꾸어 실행할 수 있다.

UsingPrepareStatement.java의 메인 메소드에 아래 SQL 문을 JDBC로 실행하는 코드를 작성한다.

UPDATE NAMECARD SET COMPANY=? WHERE NO=?

JDBC 코드는 아래 순서를 참조한다.

  1. JDBC 드라이버 로딩
  2. Connection 맺기
  3. SQL 실행
  4. [SQL문이 select문이었다면 ResultSet을 이용한 처리]
  5. 자원 반환
UsingPrepareStatement.java
package net.java_school.jdbc.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class UsingPreparedStatement {
	static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:XE";
	static final String USER = "scott";
	static final String PASS = "tiger";
	
	public static void main(String[] args) {
		// JDBC 드라이버 로딩
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Connection con = null;
		PreparedStatement pstmt = null;
		String sql = "UPDATE NAMECARD SET COMPANY=? WHERE NO=?";
		try {
			// 커넥션 맺기
			con = DriverManager.getConnection(URL, USER, PASS);
			// SQL 실행
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, "율도국");
			pstmt.setInt(2, 1);
			pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println(sql);
		} finally {
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

Statement을 사용할 때와 다른 부분은 아래와 같다.
pstmt = con.prepareStatement(sql);
Statement을 사용할 때와 달리 PreparedStatement을 얻기 위해 사용하는 prepareStatement 메소드의 아규먼트로 SQL문을 전달한다.
pstmt.executeUpdate();
Statement와 달리 executeUpdate() 메소드에 SQL문을 아규먼트로 전달하지 않는다.

SQL문에 ? 이 있다면 PrepareStatement의 setXXX 메소드를 이용해서 설정해야 한다.
(PreparedStatement을 쓴다고 SQL 문에 반드시 물음표(?)를 포함해야 하는 건 아니다.)
XXX 부분은 해당 컬럼의 데이터 형에 매핑되는 자바 데이터 형으로 결정한다.
setXXX 메소드의 첫번째 파라미터는 ?가 위치하고 있는 순서다.
setXXX 메소드의 두번째 파라미터는 ?를 대체할 값이다.

PreparedStatement 대신에 Statement을 꼭 써야 하는 경우는 거의 없다.
때문에 이제부터는 PreparedStatement만을 사용하도록 하자.