JDBC・パラメータのバインド

 SQL文の実行は大きく (1)SQL文の解析 (2)文の実行 (3)結果の取得に分けられます。 同じ形状のSQL文を繰り返し実行する場合、 SQL文の解析だけを行ったものに毎回値を当てはめるようにすれば毎回SQL文の解析を行う時間がセーブできます (SQL*Plusのバインド変数の概念にとてもよく似ています)。 これを行うには、Connectionの createStatementの代わりに prepareStatementを使います。

import java.sql.*;
import java.io.*;
import java.util.Properties;

public class OciPrepareTester {
  public static void main (String args []) {
    try {
      // Oracle JDBC driverをロードします。
      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

      // 接続情報をセットします。ユーザー、パスワード、ホスト文字列
      // (TNS接続文字列)をSQL*Plusのログオン時と同様に指定します。
      Properties p = new Properties();
      p.put("user", "URANO");
      p.put("password", "URANO398");

      Connection conn =
	DriverManager.getConnection ("jdbc:oracle:thin:@eodb", p);
      System.out.println ("connected.");

      // SQL文(DML文)を作ります。パラメータの部分には「?」文字を
      // 入れておきます。
      PreparedStatement pstmt = conn.prepareStatement(
        "SELECT * FROM PARTS WHERE PARTS_CLASS = ?"
      );

      // ?にあたるパラメータにsetIntやsetStringメソッドで実際の値を
      // セットします。最初の引数はインデックス(SQL文中で?が出てくる順番)、
      // 次の引数が値です。
      pstmt.setString(1, "CL016");

      // executeQueryやexecuteUpdateを引数なしでコールします。
      ResultSet rset = pstmt.executeQuery();

      while (rset.next ()){
	System.out.println ("品目コード:" + rset.getString(3) +
          "\t名前:" + rset.getString("name"));
      }
      // 結果セットを解放
      rset.close();
      // SQL文を解放
      pstmt.close();
      // データベースから切断して、完了。
      conn.close();
    } catch(SQLException ex){
      System.out.println("Ootto! Exception Caught: " + ex.getMessage());
      ex.printStackTrace();
    }
  }
}
// end.

 prepareStatementメソッドの引数で指定するSQL文には 「後で指定したい」値の部分に「?」を補っておきます。 「?」は1つの文中に何個でも指定できます。

  PreparedStatement pstmt = conn.prepareStatement(
    "SELECT * FROM PARTS WHERE PARTS_CLASS = ?"
  );

 そして、いざ実行の前に各「?」に当たる実際の値を PreparedStatementクラスのメソッドsetIntsetStringでセットします。 最初の引数は「?」のインデックス (当該値をSQL文の何番目に出てくる「?」の位置に当てはめるか。1〜) を指定します。2番目の引数がその値です。

  pstmt.setString(1, "CL016");

 実行にはexecuteexecuteQueryexecuteUpdateを引数なしで使います。

  ResultSet rset = pstmt.executeQuery();


ちょっとメモ(1) - java.util.Propertiesの使用

 Oracleサーバーに接続するときのgetConnection の引数に、Propertiesクラスのインスタンスを使うことができます。

  Properties p = new Properties();
  p.put("user", "URANO");
  p.put("password", "URANO398");
  Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@eodb", p);

「user」と「password」以外にも、 トランザクションの動作を規定するパラメータが幾つかあります。 詳しくはマニュアル等をご覧ください。


ちょっとメモ(2) - SQLExceptionのデバッグ

 SQLExceptionには、例外が飛んだときの呼び出し階層を表示する機能があります。 例外が飛んだときこれを使えば、デバッグが多少楽になります。

  try {
    // Transaction
  } catch(SQLException ex){
    System.out.println("Ootto! Exception Caught: " + ex.getMessage());
    ex.printStackTrace();
  }

JDBC and Swing Top

(first uploaded 2001/01/08 last updated 2002/03/02, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル