JDBC Statement PreparedStatement CallableStatement

JDBC 응용 프로그램에서 JDBC 문장 대상은 SQL 문장을 데이터베이스 서버에 보내는 데 사용됩니다.하나의 문장 대상은 하나의 연결과 연결되고 응용 프로그램과 데이터베이스 서버 간의 통신은 문장 대상이 처리한다.
JDBC에는 다음과 같은 세 가지 유형의 문 객체가 있습니다.
    1.일반 문
    2.사전 설정 문(Prepared statement)
    3.호출 가능 명령문(Callable statement)
문장 대상은 하나의 연결과 연결되어 있기 때문에 문장 대상을 만들려면 먼저 데이터베이스 연결을 만들어야 한다.연결된 검색은 이전 블로그를 보십시오.
이 세 가지 문장에 관해서 개인적으로 가장 가치가 있다고 생각하는 것은 바로 예치문장이다. 다음은 왜
1) 미리 설정된 문장은 sql 매개 변수의 주입을 피할 수 있다.일반적인statement를 사용하면 사용자는 sql 문장을 주입하여 매개 변수로 입력해야 할 변수를 SQL 주입 변수로 바꿀 수 있습니다.그러나 사전 설정 문을 사용하면 변수의 값이 SQL로 전달될 수 없습니다.이것은 검색할 때 조건을 or 1=1로 설정하면 나타납니다.
2) 문장을 한 번만 컴파일하면 효율적으로 조작할 수 있기 때문이다.템플릿 SQL에 대해 우리는 여러 번 실행해야 할 수도 있다. 매번 들어오는 매개 변수만 다르면 일반적인 문장을 사용하면 실행할 때마다 데이터베이스에서 한 번 컴파일하지만, 미리 설정된 문장을 사용하면 한 번만 컴파일할 수 있어 효율이 크게 높아진다.
3) 미리 설정된 문장은 대량으로 조작할 수 있다.일부 특수한 업무 논리 처리에 대해 우리는 한 번에 여러 개의 데이터를 업데이트할 수 있지만, 우리가 매번 문장을 가져와서 SQL을 실행하면 효율이 떨어질 수밖에 없다. 그러나 미리 설정된 문장의 대량 조작을 사용하면 효율이 많이 향상될 것이다.
4) 업데이트 가능한 결과집과 스크롤 가능한 결과집에 대해 다음 블로그에서 결과집을 설명하자면 대량 작업과 결과집의 스크롤과 업데이트는 미리 설정된 문장만의 장점이 아니라 일반적인 문장도 실현할 수 있다. 미리 설정된 문장의 두 가지 특징은 바로 미리 편집하고 SQL 문장이 변수로 주입되는 것을 방지하는 것이다.
다음은 세 가지 문장에 대한 상세한 소개로, 내용은
 http://blog.csdn.net/athenaer/article/details/8696311
일반문
연결createStatement 방법으로 이 문장을 만들 수 있습니다.이 문은 매개변수로 값을 전달할 필요가 없는 SQL 문에만 사용됩니다.
명세서창설 문장의 예시 코드를 보여 줍니다.
                Statement stmt = con.createStatement();
      cmd = "create database testDB;";
      rc = stmt.executeUpdate(cmd);
stmt.close();

미리 설정된 문장
미리 설정된 문장은statement 클래스의 하위 클래스입니다.미리 설정된 문장과statement류의 주요 차이점은 전자는 한 번만 컴파일하고 최적화한 다음에 서로 다른 매개 변수 값을 설정하여 여러 번 사용할 수 있다는 것이다.따라서 한 문장을 여러 번 집행하고 싶다면 미리 설정한 문장이 더 좋은 선택이다.미리 컴파일되었기 때문에 실행 시간을 줄였다.따라서 사전 설정 문장의 장점은 SQL 문장을 포함할 뿐만 아니라 미리 컴파일된 SQL 문장도 포함한다는 것이다.또 다른 차이점은 SQL 문이 만들어진 후 사전 설정 문에 제공된다는 것입니다.
명세서미리 설정된 문장의 예시 코드를 설명하다
                PreparedStatement pstmt = con.prepareStatement("UPDATE tab1 "+
                    "set col1 = ? where key = 1");
pstmt.setShort(1, (short)2);
int rowcount = pstmt.executeUpdate();

여기서 같은 미리 설정된 문장은 다른col1값에 사용할 수 있습니다.매개 변수가 설정되면 다시 설정되거나 clearParameters 호출될 때까지 값이 변하지 않습니다.이 특성으로 인해 미리 설정된 문장은 대량 처리INSERT/UPDATE에 사용할 수 있다.
대량 업데이트
여러 개의 값을 설정함으로써, 대량 업데이트 기능은 여러 번 실행해야 하는 문장의 성능을 향상시켰다.이렇게 하면 여러 개의 업데이트 작업을 하나의 데이터 원본에 제출하고 일회성 처리를 할 수 있다.문장 대상도 대량 업데이트를 사용할 수 있다.그러나 문장 대상은 서로 다른 SQL 문장을 일괄 처리하고, 미리 설정된 문장은 하나의 매개 변수를 제출한다.
목록 4는 대량 삽입을 위해 미리 설정된 문을 사용하는 방법을 보여 줍니다.
명세서대량 업데이트의 예시 코드를 보여 줍니다.
                PreparedStatement pst = conn.prepareStatement("insert into tab1 values (?)");
for loop....
{
	pst.setInt (1, i);
	pst.addBatch();
}
pst.executeBatch();
addBatch 방법은 문장을 캐시에 추가한 다음executeBatch() 방법으로 데이터베이스에 저장한다.그래서 문장의 컴파일링/최적화를 절약했다. 한 번만 컴파일하기 때문에(예치된 문장에) 서버와의 왕복도 절약했다. 왜냐하면 한 번에 대량 삽입을 보냈기 때문이다.
호출 가능 문장
이것은 SQL 문장을 호출하는 세 번째 방법으로 자바에서™ 프로그램에서 서버의 저장 프로세스를 호출하는 방식입니다.호출 가능한 문장도 먼저 준비를 한 다음에 set 방법으로 그것들의 매개 변수를 설정해야 한다.다음 두 가지 방법으로 매개변수 값을 설정할 수 있습니다.
  • 순서 위치
  • 명명 매개 변수
  • 순서 위치는 전통적인 매개 변수 설정 방식으로 매개 변수가 Callable Statements에 있는 위치에 따라 매개 변수를 설정합니다.그러나 명명 매개 변수는 순서가 아닌 이름에 따라 매개 변수를 설정할 수 있는 유연성을 제공한다.루틴을 호출할 때는 Callable Statement의 매개 변수를 이름이나 순서로 지정해야 합니다.예를 들어, 매개변수에 매개변수 이름을 사용하는 경우 다른 모든 매개변수에도 매개변수 이름을 사용해야 합니다.
    많은 파라미터가 있고, 그 중 일부 파라미터가 기본값이 있는 저장 프로세스를 호출할 때, 명명 파라미터는 특히 유용하다.프로세스가 유일하면 기본값이 있는 인자를 생략할 수 있고, 임의의 순서대로 인자를 입력할 수 있습니다.이름 파라미터는 프로그램을 더욱 튼튼하게 하기 때문에 저장 과정에서 파라미터의 순서가 바뀌어도 프로그램을 수정할 필요가 없습니다.
    JDBC 드라이버는 드라이버와 RDMS가Callable Statement의 명칭 파라미터를 지원하는지 확인하는 방법을 제공합니다.이름 지정 매개변수가 지원되면 true가 반환됩니다.예를 들면 다음과 같습니다.
    명세서supportsNamedParameters() 사용
                    Connection myConn = . . .   // connection to the RDBMS for Database
          DatabaseMetaData dbmd = myConn.getMetaData();
          if (dbmd.supportsNamedParameters() == true)
          {
              System.out.println("NAMED PARAMETERS FOR CALLABLE"
                                + "STATEMENTS IS SUPPORTED");
          }

    저장 프로세스의 매개 변수 이름 가져오기DatabaseMetaData.supportsNamedParameters()DatabaseMetaData 를 사용하여 저장 프로세스의 매개 변수 이름을 얻을 수 있습니다. 이 방법의 정의는 명세서 6과 같습니다.
    명세서getProcedureColumn () 방법의 사용
                    Connection myConn = . . .   // connection to the RDBMS for Database
     . .
          DatabaseMetaData dbmd = myConn.getMetaData();
          ResultSet rs = dbmd.getProcedureColumns(
           "myDB", schemaPattern, procedureNamePattern, columnNamePattern);
          rs.next() {
              String parameterName = rs.getString(4);
     - - - or - - -
     String parameterName = rs.getString("COLUMN_NAME"); 
     - - -
              System.out.println("Column Name: " + parameterName);
    getprocedureColumns 방법의 매개 변수와 일치하는 모든 열의 이름이 표시됩니다.
    목록 7은 Callable Statements에서 명명된 매개변수의 사용을 보여줍니다.
    저장 프로세스 생성
    명세서OUT 매개변수 사용 호출 가능
                    create procedure createProductDef(productname   varchar(64),
                     productdesc  varchar(64),
                     listprice    float,
                     minprice     float,
                 out prod_id      float);
    . . .
      let prod_id="value for prod_id";
    end procedure;

    목록 8의 자바 코드는 먼저 5개의 파라미터가 있는Callable Statement를 만듭니다. 이 5개의 파라미터는 저장 과정의 파라미터와 대응합니다.JDBC에서 호출한 괄호의 물음표 문자(?)매개변수를 참조합니다.모든 매개 변수를 설정하거나 등록합니다.cstmt 형식 사용setString("arg", name);매개 변수를 명명합니다. 그 중에서arg는 상응하는 저장 과정 중의 매개 변수 이름입니다.여기에는 저장 과정 중의 매개 변수 순서에 따라 매개 변수를 명명할 필요가 없다.
    명세서이름 지정 매개변수 사용 호출 가능
                    String sqlCall = "{call CreateProductDef(?,?,?,?,?)}";
          CallableStatement cstmt = conn.prepareCall(sqlCall);
    
          cstmt.setString("productname", name);     // Set Product Name.
          cstmt.setString("productdesc", desc);     // Set Product Description.
          cstmt.setFloat("listprice", listprice);   // Set Product ListPrice.
          cstmt.setFloat("minprice", minprice);     // Set Product MinPrice.
    
          // Register out parameter which should return the product is created.
    
          cstmt.registerOutParameter("prod_id", Types.FLOAT);
    
          // Execute the call.
          cstmt.execute();
    
          // Get the value of the id from the OUT parameter: prod_id
          float id = cstmt.getFloat("prod_id");

    Callable Statement의 매개 변수 수가 저장 프로세스의 매개 변수 수보다 적으면 나머지 매개 변수는 기본값이 있어야 합니다.서버가 자동으로 기본값을 사용하기 때문에 기본값이 있는 매개 변수에 값을 설정할 필요가 없습니다.예를 들어 저장 프로세스에 10개의 파라미터가 있는데 그 중 4개의 파라미터가 기본값이 없고 6개의 파라미터가 기본값이 있다면 Callable Statement에 적어도 4개의 물음표가 있어야 한다.5개, 6개 또는 최대 10개의 물음표를 사용할 수도 있다.다음 유일한 저장 과정 중, 매개 변수 getProcedureColumns()listprice 는 기본값이 있습니다.
    명세서기본값을 포함하는 매개변수를 작성하는 과정
                    create procedure createProductDef(productname   varchar(64),
                     productdesc  varchar(64),
                     listprice    float default 100.00,
                     minprice     float default  90.00,
                 out prod_id      float);
    . . .
      let prod_id = value for prod_id;
    end procedure;

    명세서 10의 자바 코드는 저장 과정 중의 매개 변수보다 적은 매개 변수(저장 과정 중 5개의 매개 변수가 있고 코드 중 4개의 매개 변수만 사용)를 사용하여 저장 과정을 호출합니다.minprice에는 기본값이 있기 때문에 Callable Statement에서 생략할 수 있습니다.
    명세서기본 매개변수 사용
                    String sqlCall = "{call CreateProductDef(?,?,?,?)}";
                                                  // 4 params for 5 args
          CallableStatement cstmt = conn.prepareCall(sqlCall);
    
          cstmt.setString("productname", name);   // Set Product Name.
          cstmt.setString("productdesc", desc);   // Set Product Description.
        
          cstmt.setFloat("minprice", minprice);   // Set Product MinPrice.
    
          // Register out parameter which should return the product id created.
    
          cstmt.registerOutParameter("prod_id", Types.FLOAT);
    
          // Execute the call.
          cstmt.execute();
    
          // Get the value of the id from the OUT parameter: prod_id
          float id = cstmt.getFloat("prod_id");

    호출 가능한 문장에 listprice 또는 OUT 인자가 포함되어 있다면, 이 인자들을 Callable Statement의 INOUT로 등록해야 합니다.명세서 11은 registerOutParameter 파라미터out를 사용하여 prod_id 파라미터를 가진 저장 프로세스를 만듭니다.이와 유사하게 키워드OUT를 사용하여 INOUT 파라미터를 만들 수 있습니다.
    명세서INOUT 및 OUT 매개변수 사용
                    create procedure createProductDef(productname   varchar(64),
                     productdesc  varchar(64),
                 inout    listprice    float default 100.00,
                     minprice     float default  90.00,
                 out prod_id      float);

    명세서 12는 Callable StatementsINOUT 방법으로 Callable Statement의registerOutparameter 파라미터를 등록합니다.
    명세서CallableStatement를 사용하여 OUT 매개변수 등록
                    cstmt.registerOutParameter("prod_id", Types.FLOAT);

    명세서 13은 명명된 매개변수 특성을 사용하는 모든 문을 결합합니다.
    명세서명명된 매개변수 기능을 보여 주는 프로그램
                    package Callable;
    
    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.Types;
    public class out1 {
        static Connection conn;	
        public static void main(String[] args) {
            getConnect();
            System.out.println("Connection Established");
            createProc();
            runthis();
            System.out.println("
    =============Finished=============");         System.exit(0);     }     private static void getConnect() {         try         {             Class.forName("com.informix.jdbc.IfxDriver");             String url = "jdbc:informix-sqli://host name or ip :porn number/database                  name:informixserver=dbservername;";             System.out.println("URL: "+url);             conn = DriverManager.getConnection(url);             }         catch( Exception e )         {             e.printStackTrace();             System.exit(1);         }     }     private static void createProc() {         String str=null;         Statement stmt = null;         try          {             stmt = conn.createStatement();         }          catch (SQLException e2)          {             e2.printStackTrace();         }         str="drop function c_out_proc";         try          {             stmt.executeUpdate (str);         }          catch (SQLException e1)          { }         str = "create function  c_out_proc ( i int, OUT d varchar(20) ) 
    " +         "returning float; 
    " +         "define f float; 
    " +         "let d= \"Hello OUT\"; 
    " +         "let f=i*2; 
    " +         "return f; 
    " +          "end function; 
    ";         try         {             stmt.executeUpdate (str);             System.out.println("Function created 
    ");         }         catch (SQLException e)         {             System.out.println("Error on creating function: " + e.toString());             System.exit(1);         }     }     private static void runthis()      {         CallableStatement cstmt = null;         String command = "{? = call c_out_proc(?, ?)}  ";         try          {             cstmt = conn.prepareCall (command);             cstmt.setInt(1, 2);             cstmt.registerOutParameter(2, Types.VARCHAR);             ResultSet rs = cstmt.executeQuery();             if (rs == null)             {                 System.out.println("rs is null *** this is BAD.");                 System.exit(0);             }             else             {                 rs.next();                 System.out.println(rs.getFloat(1));                 System.out.println(cstmt.getString(2));             }         }          catch (SQLException e)          {             e.printStackTrace();         }     } }

    좋은 웹페이지 즐겨찾기