본문으로 바로가기






자바에서 데이터베이스로 쿼리문을 전송할 때 사용할 수 있는 인터페이스가 2가지 있다. Statement와 PreparedStatement이다. 둘다 쿼리 전송기능을 가지고 있지만 차이점이 있다. 어떤 점이 차이가 나고, 어느 인터페이스를 사용하는 것이 좋은지 자세하게 알아보자.




공통점


  1. 두 인터페이스 모두 SQL 질의문을 전달하는 역할을 한다.

  2. 사용시 반드시 try~catch문 또는 throws 처리를 해야한다.



Statement (인터페이스)


  1. Statement 객체는 Statement 인터페이스를 구현한 객체를 Connection 클래스의 createStatement( ) 메소드를 호출함으로써 얻어진다.

  2. Statement 객체가 생성되면 executeQuery( ) 메소드를 호출하여 SQL문을 실행시킬 수 있다. 메소드의 인수로 SQL문을 담은 String객체를 전달한다.

  3. Statement는 정적인 쿼리문을 처리할 수 있다. 즉 쿼리문에 값이 미리 입력되어 있어야 한다.



<Connection 인터페이스 API>





PreparedStatement (인터페이스)


  1. PreparedStatement 객체는 Connection 객체의 preparedStatement( ) 메소드를 사용해서 생성한다. 이 메소드는 인수로 SQL문을 담은 String객체가 필요하다.

  2. SQL문장이 미리 컴파일되고, 실행 시간동안 인수값을 위한 공간을 확보할 수 있다는 점에서 Statement 객체와 다르다. 

  3. Statement 객체의 SQL은 실행될 때 매번 서버에서 분석해야 하는 반면, PreparedStatement 객체는 한 번 분석되면 재사용이 용이하다.

  4. 각각의 인수에 대해 위치홀더(placeholder)를 사용하여 SQL문장을 정의할 수 있게 해준다. 위치홀더는 ? 로 표현된다.

  5. 동일한 SQL문을 특정 값만 바꾸어서 여러 번 실행해야 할 때, 인수가 많아서 SQL문을 정리해야 될 필요가 있을 때 사용하면 유용하다.



<Connection 인터페이스 API>





예제



  • 테이블


1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE TEST 
(
  ID VARCHAR2(20NOT NULL 
, PW VARCHAR2(20NOT NULL 
, NAME VARCHAR2(20NOT 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 객체는 작은따옴표 문제를 쿼리 실행시 자동으로 처리하므로 신경쓸 필요가 없다는 장점이 있다.



RSS구독 링크추가 트위터 이메일 구독