자바 - JDBC PreparedStatement, CallableStatement
- PreparedStatetment
Statement 의 execute 메소드는 문자열로 구성된 SQL 구문을 DBMS로 전달하며 내부적으로 SQL 구문을 JDBC 드라이버가 읽을 수 있는 형식으로 전처리(precompile) 하게 된다.이후 드라이버는 DBMS 에 전처리된 요구사항을 전송하게 되는데, SQL 구문을 매번 전처리 과정을 거쳐서 전송하게 되기 때문에 반복적인 작업에서 속도가 느려질 수 있는 한계를 갖고 있다.
이에 반하여, PreparedStatement는 전처리된 Statement로 주어진 SQL 구문을 미리 전처리 과정을 거친 상태로 보관해 두기 때문에 반복적인 작업에 있어서 매우 유리하다.
// preparedStatement 객체 생성을 위한 sql 문은 미리 준비되어야 한다.
String sql = "INSERT INTO TABLE VALUES(?, ?)";
PreparedStatement pstmt = new Connection().prepareStatement(sql);
이 때 '?' 는 set.Xxx 메소드에 의해 설정되며, 문자열일지라도 작은 따옴표는 넣지 않는다.
pstmt.setInt(1, 100);
pstmt.setString(2, "누구게");
PreparedStatement 객체를 생성하면서 sql 문을 매개변수로 넘겨주었기 때문에 executeUpdate(), executeQuery() 메소드는 매개변수 없이 사용한다.
- CallableStatement
프로시저 호출은 CallableStatement 객체를 사용하며 sql 문자열을 미리 선언하고 초기화 해야 하는 것은 동일하지만 그 형태는 다르다.
// {} 로 문장을 감싸고 execute가 아닌 call 로 프로시저를 호출한다.
String sql = "{call PROCEDURE_NAME(?, ?)}"
CallableStatement cstmt = new Connection().prepareCall(sql);
이하 매개변수(?) 셋팅과 executeUpdate() 를 사용하는 것은 동일하다.
그렇다면!!!! 커서(CURSOR)가 OUT 매개변수로 구성된 프로시저는??
1. 프로시저에서 OUT 매개변수로 SYS_REFCURSOR 를 사용한다.
CREATE OR REPLACE PROCEDURE PRC
( RESULT OUT SYS_REFCURSOR
)
IS
-- SYS_REFCURSOR는 여기서 커서를 정의(선언)하지 않는다.
BEGIN
OPEN RESULT FOR
SELECT VAL1, VAL2, VAL3
FROM TABLE;
END;
이 때, 참조 형태의 커서는 프로시저 내부에서 CLOSE() 하지 않는다! => 닫으면 커서를 받은 저쪽(참조하는 쪽)에서 사용할 수 없음.
2.
CallableStatement 의 registerOutParameter() 메소드에 OracleTypes.CURSOR를 매개변수로 넘겨준다
그 후 그냥 execute() 메소드 호출 -> getObject 로 Object 형식의 리턴값 받아오고 ResultSet 으로 다운캐스팅~!!
String sql = "{call PRC(?)}";
CallableStatement cstmt = new Connection().prepareCall(sql);
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
ResultSet rs = (ResultSet)cstmt.getObject(1);
사실... CallableStatement 는 아직 감이 잘^_^... 공부공부 아자아자~!