9.3 LOB用のJDBC API

JDBCでは、CLOBおよびBLOB用の標準Javaインタフェースjava.sql.Clobおよびjava.sql.Blobがそれぞれサポートされています。

JDBCでは、ロケータではなく、Java APIのメソッドおよびプロパティを使用してLOBに対する操作を実行します。

ResultSetの一部としてBLOBオブジェクトとCLOBオブジェクトが取り出された場合、これらのオブジェクトは現在選択されている行のLOBロケータを表します。移動操作(rset.next()など)によってカレント行が変更されても、取り出されたロケータは元のLOB行を参照したままです。移動操作が行われるたびに、インスタンスがBLOBCLOBまたはBFILEのいずれであるかに応じて、ResultSetgetBLOB()getCLOB()またはgetBFILE()をコールする必要があります。

関連項目:

LOBとBFILEの操作

LOBデータのプリフェッチ

JDBCクライアントを使用する場合、フェッチ中にLOBロケータと一緒にデータおよびメタデータ(長さおよびチャンク・サイズ)の一部をプリフェッチすると、サーバー・ラウンドトリップ数を削減できます。これは、永続LOB、一時LOBおよびBFILEに適用されます。サイズが小さいLOBから中程度のLOBの場合、ほとんどのLOBがプリフェッチ・サイズより小さくなるようにプリフェッチ長を設定することをお薦めします。

LOBプリフェッチ・サイズはセッション・レベルで設定でき、文レベルまたは列レベルで上書きできます。プリフェッチ・サイズの値は次のとおりです。
  • -1 プリフェッチの無効化
  • 0 メタデータに対してのみプリフェッチを有効化
  • フェッチ操作中にロケータと一緒にプリフェッチされる、BLOBのバイト数およびCLOBの文字数を表す0より大きい任意の値。
prop.setPropertyを使用して、セッションのプリフェッチ・サイズを設定します。JDBC Thinドライバのデフォルトのセッション・プリフェッチ・サイズは32kです。
prop.setProperty("oracle.jdbc.defaultLobPrefetchSize","64000");

セッション・レベルのデフォルトのプリフェッチ・サイズは、次のように文レベルで上書きできます。

((OracleStatement)stmt).setLobPrefetchSize(100000);

次のコード・スニペットを使用して、文のプリフェッチ・サイズをフェッチできます。

int pf = ((OracleStatement)stmt).getLobPrefetchSize() ;

セッション・レベルのデフォルトのプリフェッチ・サイズは、次のように列レベルで上書きできます。

((OracleStatement)stmt).defineColumnType(1, OracleTypes.CLOB, /*lobPrefetchSize*/
      32000);

表9-3 LOB用のJDBCメソッド

分類 関数およびプロシージャ 説明
その他 empty_lob() 空のLOBを作成
isSecureFile() BLOBまたはCLOBロケータがSecureFileかどうかを確認
オープンとクローズ open() LOBをオープン
isOpen() LOBがオープンしているかどうかの確認
close() LOBのクローズ
読取り操作 length() LOB長の取得
getChunkSize() 最適な読取りまたは書込みサイズの取得
getBytes() 指定されたオフセットのBLOBからのデータの読取り
getBinaryStream() BLOBをバイナリ・ストリームとしてストリーム
getChars() 指定されたオフセットのCLOBからのデータの読取り
getCharacterStream() CLOBを文字ストリームとしてストリーム
getAsciiStream() CLOBをASCIIストリームとしてストリーム
getSubString() 指定されたオフセットからLOB値の一部を返す
position() LOB内のパターンの一致位置を返す
変更操作 setBytes() 指定されたオフセット位置でのBLOBへのデータの書込み
setBinaryStream() BLOB値への書込みに使用できるバイナリ・ストリームの設定
setString() 指定されたオフセット位置でのCLOBへのデータの書込み
setCharacterStream() CLOB値への書込みに使用できる文字ストリームの設定
setAsciiStream() CLOB値への書込みに使用できるASCIIストリームの設定
truncate() LOB値の指定された長さまでの切捨て
複数のロケータを含む操作 dst = src LOBロケータsrcのLOBロケータdstへの割当て

例9-3 LOB用のJDBC API

static void jdbc_lob_apis() throws Exception {
 
  System.out.println("Persistent LOBs Test in JDBC "+ TYPE);
  try(
      Connection con = getConnection();
      Statement       stmt = con.createStatement();
      )
  {
 
    ResultSet   rs      = null;
    Clob  c1      = null;
    Clob  c2      = null;
    Reader      in      = null;
    long        pos     = 0;
    long        len     = 0;
 
    rs = stmt.executeQuery("select ad_sourcetext from print_media where product_id = 1");
    rs.next();
    c1 = rs.getCLOB(1);
    OracleClob c11 = (OracleClob)c1;
    rs.close();
 
    /*------------------------------------------------------------------*/
    /*---------------------- Sanity Checking ---------------------------*/
    /*------------------------------------------------------------------*/
    if (c11.isSecureFile())
      System.out.println("C1 is a Securefile LOB");
    else
      System.out.println("C1 is a Basicfile LOB");
 
 
    /*------------------------------------------------------------------*/
    /*----------------------- Open/Close -------------------------------*/
    /*------------------------------------------------------------------*/
 
    /*----------------------- Opening a CLOB ---------------------------*/
    c11.open(LargeObjectAccessMode.MODE_READONLY);
 
    /*-------------- Determining Whether a CLOB Is Open ----------------*/
    if (c11.isOpen())
      System.out.println("C11 is open!");
    else
      System.out.println("C11 is not open");
 
    /*----------------------- Closing a CLOB ---------------------------*/
    c11.close();
 
    /*-------------------------------------------------------------------*/
    /*-------------------- Reading from a LOB ---------------------------*/
    /*-------------------------------------------------------------------*/
 
    /*------------------------ Get CLOB Length -------------------------*/
    len = c1.length();
    System.out.println("CLOB length = " + len);
 
    /*------------------------ Reading CLOB Data -----------------------*/
    char[] readBuffer = new char[6];
    in = c1.getCharacterStream();
    in.read(readBuffer,0,5);
    in.close();
    String lobContent = new String(readBuffer);
    System.out.println("Buffer with LOB contents: " + lobContent);
 
    /*----------------------- Substr of a CLOB -------------------------*/
    String subs = c1.getSubString(2, 5);
    System.out.println("LOB substring: " + subs);
 
 
    /*----------------------- Search for a pattern  --------------------*/
    pos = c1.position("aaa", 1);
    System.out.println("Pattern matched at position = " + pos);
 
    /*------------------------------------------------------------------*/
    /*-------------------- Modifying a LOB -----------------------------*/
    /*------------------------------------------------------------------*/
 
    rs = stmt.executeQuery("select ad_sourcetext from print_media where product_id = 1 for update");
    rs.next();
    c2 = rs.getClob(1);
    OracleClob c22 = (OracleClob)c2;
 
    /*-------------------- Write to a CLOB ----------------------------*/
    c22.open(LargeObjectAccessMode.MODE_READWRITE);
    c2.setString(3,"modified");
    String msubs = c2.getSubString(1, 15);
    System.out.println("Modified LOB substring: " + msubs);
 
    /*-------------------- Truncate a CLOB ----------------------------*/
    c2.truncate(20);
    len = c2.length();
    System.out.println("Truncated LOB len = " + len);
    c22.close();
 
  }
}