자바에서 데이터베이스로 쿼리문을 전송할 때 사용할 수 있는 인터페이스가 2가지 있다. Statement와 PreparedStatement이다. 둘다 쿼리 전송기능을 가지고 있지만 차이점이 있다. 어떤 점이 차이가 나고, 어느 인터페이스를 사용하는 것이 좋은지 자세하게 알아보자.
공통점
두 인터페이스 모두 SQL 질의문을 전달하는 역할을 한다.
사용시 반드시 try~catch문 또는 throws 처리를 해야한다.
Statement (인터페이스)
Statement 객체는 Statement 인터페이스를 구현한 객체를 Connection 클래스의 createStatement( ) 메소드를 호출함으로써 얻어진다.
Statement 객체가 생성되면 executeQuery( ) 메소드를 호출하여 SQL문을 실행시킬 수 있다. 메소드의 인수로 SQL문을 담은 String객체를 전달한다.
Statement는 정적인 쿼리문을 처리할 수 있다. 즉 쿼리문에 값이 미리 입력되어 있어야 한다.
<Connection 인터페이스 API>
PreparedStatement (인터페이스)
PreparedStatement 객체는 Connection 객체의 preparedStatement( ) 메소드를 사용해서 생성한다. 이 메소드는 인수로 SQL문을 담은 String객체가 필요하다.
SQL문장이 미리 컴파일되고, 실행 시간동안 인수값을 위한 공간을 확보할 수 있다는 점에서 Statement 객체와 다르다.
Statement 객체의 SQL은 실행될 때 매번 서버에서 분석해야 하는 반면, PreparedStatement 객체는 한 번 분석되면 재사용이 용이하다.
각각의 인수에 대해 위치홀더(placeholder)를 사용하여 SQL문장을 정의할 수 있게 해준다. 위치홀더는 ? 로 표현된다.
동일한 SQL문을 특정 값만 바꾸어서 여러 번 실행해야 할 때, 인수가 많아서 SQL문을 정리해야 될 필요가 있을 때 사용하면 유용하다.
<Connection 인터페이스 API>
예제
테이블
1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE TEST ( ID VARCHAR2(20) NOT NULL , PW VARCHAR2(20) NOT NULL , NAME VARCHAR2(20) NOT NULL , CONSTRAINT TABLE1_PK PRIMARY KEY ( ID ) ENABLE ); | cs |
DBConnection.java (오라클 연결을 위한 클래스)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class DBConnection { public static Connection dbConn; public static Connection getConnection() { Connection conn = null; try { String user = "scott"; String pw = "tiger"; String url = "jdbc:oracle:thin:@localhost:1521:orcl"; Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection(url, user, pw); System.out.println("Database에 연결되었습니다.\n"); } catch (ClassNotFoundException cnfe) { System.out.println("DB 드라이버 로딩 실패 :"+cnfe.toString()); } catch (SQLException sqle) { System.out.println("DB 접속실패 : "+sqle.toString()); } catch (Exception e) { System.out.println("Unkonwn error"); e.printStackTrace(); } return conn; } } | cs |
StatementTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import java.sql.Statement; import java.sql.Connection; import java.sql.SQLException; public class StatementTest { public static void main(String args[]) { Connection conn = null; // DB연결된 상태(세션)을 담은 객체 Statement stm = null; // SQL 문을 나타내는 객체 try { conn = DBConnection.getConnection(); stm = conn.createStatement(); String quary = "INSERT INTO TEST VALUES('id1', 'pw1', 'name1')"; int success = stm.executeUpdate(quary); if(success > 0) System.out.println("데이터 입력 성공"); else System.out.println("데이터 입력 실패"); } catch (SQLException sqle) { sqle.printStackTrace(); } } } | cs |
PreparedStatementTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import java.sql.Connection; import java.sql.SQLException; import java.sql.PreparedStatement; public class PreparedStatementTest { public static void main(String args[]) { Connection conn = null; // DB연결된 상태(세션)을 담은 객체 PreparedStatement pstm = null; // SQL 문을 나타내는 객체 try { String quary = "INSERT INTO TEST VALUES(?, ?, ?)"; conn = DBConnection.getConnection(); pstm = conn.prepareStatement(quary); // 쿼리에 값을 세팅한다. // 여기서 1, 2, 3은 첫번째, 두번째, 세번째 위치홀더 라는 뜻 pstm.setString(1, "id2"); pstm.setString(2, "pw2"); pstm.setString(3, "name2"); int success = pstm.executeUpdate(); if(success > 0) System.out.println("데이터 입력 성공"); else System.out.println("데이터 입력 실패"); } catch (SQLException sqle) { sqle.printStackTrace(); } } } | cs |
StatementTest.java 실행결과
PreparedStatementTest.java 실행결과
어떤 것을 사용하는 것이 좋은가?
PreparedStatement를 사용하는 것이 좋다. PreparedStatement는 동적인 쿼리문을 처리할 수 있으므로 같은 SQL문에서 값만 변경하여 사용한다던가 인수가 많은 경우에 사용하기 좋다. 또한 미리 컴파일되기 때문에 수행 속도가 Statement보다 빠른 장점이 있다.
Statement 객체는 쿼리 실행시 값에 작은따옴표( ' )가 포함되어 있으면 작은따옴표를 두 개( ' ' ) 표시해야 한다. 예를 들어 입력할 값이 I ' am 이라고 하자. 그러면 쿼리문 작성시에 값을 I ' ' am 이렇게 입력해야 한다. 그러나 PreparedStatement 객체는 작은따옴표 문제를 쿼리 실행시 자동으로 처리하므로 신경쓸 필요가 없다는 장점이 있다.
'코딩 > Java' 카테고리의 다른 글
자바 String 클래스 - 공백제거 (0) | 2016.10.18 |
---|---|
자바 String 클래스 - 문자열 자르기 (0) | 2016.10.17 |
자바와 오라클 연동하기 <2> - 소스코드 작성 (7) | 2016.09.30 |
자바와 오라클 연동하기 <1> - JDBC 드라이버 (4) | 2016.09.28 |
오버라이딩(Overriding) (0) | 2016.09.20 |