지난번 오라클 DB에 쿼리를 날리는 방식을 소개할때 Statement를 사용했습니다.
자바에서 쿼리를 생성하고 실행하는 방법을 모르시는 분은 아래 글을 참조하시길 바랍니다.
2017/11/08 - [IT/Language] - JAVA - 오라클 DB에 쿼리 날리기( INSERT, DELETE, UPDATE)
이번엔 Statement 대신 PreparedStatement를 사용하는 방법에 대해서 소개해드리겠습니다.
Statement와 PreparedStatement의 차이는 캐시 사용 유무입니다.
statement와 달리 preparedstatement는 객체를 캐시에 담아 재사용합니다.
따라서 반복적으로 쿼리를 수행한다면 statement에 비해 성능이 좋습니다.
또한, 시큐어 코딩을 보면 Statement를 사용하지말고 PreparedStatement를 사용하라는 규칙에서 볼 수 있듯이 보안적인 문제에 있어서statement는 취약점을 가지고 있기 때문에 사용하지 않는 것이 권고되고 있습니다.
그럼 이제 PreparedStatement를 어떻게 사용하는지 소개해드리겠습니다.
Statement로 구현했던 예시
먼저 지난번 포스팅 글에서 예시로 포함됐던 코드를 다시 사용하겠습니다.
보시다싶이 디비에 연결하고 쿼리를 수행할때 Statement를 사용하고 있습니다.
try { Connection conn = null; Statement stmt = null; String sql = "INSERT CUSTOMER (NAME, AGE, ADDRESS) VALUES('" + name +"'," + age + ",'" + address +"')"; conn = DriverManager.getConnection("jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid, id, password); stmt = conn.createStatement(); stmt.executeQuery(sql); stmt.close(); conn.close(); } catch(Exception e) { e.printStackTrace(); }
동일 코드에 대해 Statement가 아닌 PreparedStatement를 사용해서 예시를 만들어보도록 하겠습니다.
구조가 크게 차이가 나지는 않지만 sql문을 생성할때 차이가 있습니다. 그리고 쿼리문을 실행할때도 약간의 차이가 있습니다.
PreparedStatement를 사용하면 sql문을 생성할 때 Statement에서는 변수 값을 넣었던 것과는 달리 변수 값 대신 ? 를 사용하게됩니다.
preparedStatement로 구현한 예시
try { Connection conn = null; PreparedStatement pstmt = null; String sql = "INSERT CUSTOMER (NAME, AGE, ADDRESS) VALUES(?, ?, ?)"; conn = DriverManager.getConnection("jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid, id, password); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); pstmt.setInt(2, age); pstmt.setString(3, address); pstmt.executeUpdate(sql); stmt.close(); conn.close(); } catch(Exception e) { e.printStackTrace(); }
기존에 statement를 사용했던 코드와 차이가 보이시나요?
크게 sql 생성부분과 디비 연결 부분에서 차이가 있습니다.
이제 코드에 대해 상세히 설명해드리겠습니다.
먼저 sql문을 생성하는 부분을 보겠습니다.
String sql = "INSERT CUSTOMER (NAME, AGE, ADDRESS) VALUES(?, ?, ?)";
기존에 변수를 넣었던 부분이었던 저장할 데이터에 해당하는 VALUES의 값에 물음표( ? )를 쓰게 됩니다.
이 물음표가 들어간 자리에 추후 set~~~를 사용해서 값을 집어 넣게 됩니다. ex) setString(1, name)
지난번 statement를 사용할땐 ''를 넣어가며 sql문을 만들어서 헷갈렸을 겁니다. prepareStatement를 사용하면서 물음표로 대신하여 더 편해졌습니다.
이제 다음 부분의 코드를 살펴보겠습니다.
pstmt.setString(1, name); pstmt.setInt(2, age); pstmt.setString(3, address);
아까 쿼리문을 만들때 ?로 비워뒀던 부분에 데이터를 넣는 과정입니다. 인덱스에 해당하는 숫자는 물음표의 순번이라고 생각하시면 되겠습니다. 정해진 순서대로 변수를 채워주시면 됩니다. 물음표는 데이터가 저장되는 컬럼과 매칭시켜주시면 됩니다.
예시에선 3개의 물음표 자리에 각각 데이터를 채우고 있습니다. 첫번째 물음표엔 name을, 두번째엔 age, 그리고 세번째엔 address를 넣고 있습니다.
이렇게 물음표 순서에 맞춰서 변수값을 넣어주면 되겠습니다.
다음은 각 데이터 타입에 따라 사용하는 메소드들입니다. 데이터의 타입에 따라 set~~~를 잘 사용하시기 바랍니다.
setString(int, String) - 인덱스를 String값으로 지정합니다.
setCharacter(int, Reader, int) - 인덱스의 파라미터 값을 LONG VARCHAR로 지정합니다. / 인덱스, 읽어올 스트림, 길이 입니다.
setInt(int, int) - 인덱스를 int값으로 지정합니다.
setLong(int, long) - 인덱스를 long으로 지정합니다.
setDouble(int, double) - 인덱스를 double로 지정합니다.
setFloat(int, float) - 인덱스를 float로 지정합니다.
setTime(int, Time) - 인덱스를 java.sql.Time으로 지정합니다.
*sysdate를 사용하는 경우
sql문을 생성할때 sysdate를 넣으시면 됩니다.
String sql = "INSERT CUSTOMER (NAME, AGE, ADDRESS, ENROLLDATE) VALUES(?, ?, ?, sysdate)";
자, 그리고 이제 디비에 쿼리를 날려보겠습니다.
pstmt.executeUpdate(sql);
예시에서는 executeUpdate를 사용하고 있습니다. executeQuery와 executeUpdate의 차이가 뭘까요 ?
executeQuery는 result set을 만드는 sql문에서 사용하며, 주로 SELECT문을 수행할 때 사용됩니다.
executeUpdate는 INSERT나 UPDATE와 같은 DDL이나 DML을 실행할 때 사용됩니다.
예시에선 INSERT문을 수행하고 있으니 executeUpdate를 사용한 것입니다.
stmt.close();
conn.close();
이번에도 마찬가지로 사용한 자원들은 닫아줘야합니다.
모든 작업이 끝나고 자원을 닫아주지 않으면 나중에 문제가 발생할 수 있습니다.
자원누수는 나중에 찾기에 아주 어려운 결함입니다. 반드시 확인해주세요.
'IT > Language' 카테고리의 다른 글
오라클 쿼리문(INSERT, DELETE, UPDATE) 작성하는 법 (0) | 2017.12.08 |
---|---|
JAVA - 오라클 DB에 쿼리 날리기( INSERT, DELETE, UPDATE) (0) | 2017.12.07 |
JAVA - 오라클 트랜잭션(Transaction) 명령어 - COMMIT, ROLLBACK, SAVEPOINT (0) | 2017.12.06 |
Java DOM파서 3편 - "<"를 가진 xml파일 파싱하기(특수문자 치환) (0) | 2017.12.05 |
오라클 시퀀스(Sequence) 사용 및 .NEXTVAL 초기화 (0) | 2017.12.03 |