8.3 JavaにおけるLOB用のデータ・インタフェース
この項では、JavaにおけるLOB用のデータ・インタフェースの使用方法について説明します。
CLOB
およびBLOB
データの読取りおよび書込みは、LONG
データおよびLONG RAW
データの場合と同じストリーミング・メカニズムを使用して行うことができます。
読取り操作には、SELECT
文によって戻された永続LOBまたは一時LOBでdefineColumnType(nn, Types.LONGVARCHAR)
メソッドまたはdefineColumnType(nn, Types.LONGVARBINARY)
メソッドを使用します。これにより、VARCHAR2
またはRAW
列に類似したデータに直接ストリームが生成されます。
ノート:
VARCHAR
またはRAW
をdefineColumnType
として使用すると、選択した値は32kに切り捨てられます。ResultSet
およびCallableStatement
のgetString
やgetBytes
などの標準JDBCメソッドは、その下のLOBロケータを使用するため、データ・インタフェースの一部ではありません。
文字データをPreparedStatement
のLOB列に挿入するには、BLOB
またはCLOB
であるパラメータにsetBinaryStream()
、setCharacterStream()
またはsetAsciiStream()
を使用できます。これらの方法では、ストリーム・インタフェースを使用して、ストリーム内のデータからデータベース内にLOBを作成します。データの長さが不明である場合は、プロジェクトを向上させるために、長さパラメータを受け入れるsetBinaryStream()
またはsetCharacterStream
ファンクションのバージョンを使用します。データ・インタフェースでは、LOBデータを書き込むために、PreparedStatement
のsetString
やsetBytes
などの標準JDBCメソッドもサポートされています。これらのAPIをLOBアクセスに使用するためのコーディングが簡単になり、多くの場合は処理が高速化されます。これらの手法はすべて、データベース・ラウンドトリップを削減し、多くの場合にパフォーマンスを向上させます。
次のコード・スニペットは、すべてのJDBCドライバで機能します。
バインド:
非ストリーミング・モードの場合:
... String sql = "insert into print_media (product_id, ad_id, ad_final_text)" + " values (:1, :2, :3)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt( 1, 2 ); pstmt.setInt( 2, 20); pstmt.setString( 3, "Java string" ); int rows = pstmt.executeUpdate(); ...
ノート:
最大2 GBのサイズの文字列に対して非ストリーム・モードがサポートされていますが、マシンのメモリーが制限要因である可能性があります。ストリーミング・モードの場合、前述と同じコードが機能しますが、setString()
文は次のいずれかで置き換えられます。
pstmt.setCharacterStream( 3, new LabeledReader(), 1000000 ); pstmt.setAsciiStream( 3, new LabeledAsciiInputStream(), 1000000 );
ノート:
ストリーミング・インタフェースを使用して、ギガバイト・サイズの文字およびバイナリ・データをLOB列に挿入できます。ここで、LabeledReader()
およびLabeledAsciiInputStream()
により、それぞれ文字ストリームおよびASCIIストリームが生成されます。ad_finaltext
がCLOB
ではなくBLOB
列である場合、前述の例は、バインドがRAW
型である場合に機能します。
pstmt.setBytes( 3, <some byte[] array> ); pstmt.setBinaryStream( 3, new LabeledInputStream(), 1000000 );
ここで、LabeledInputStream()
によってバイナリ・ストリームが生成されます。
定義:
非ストリーミング・モードの場合:
OracleStatement stmt = (OracleStatement)(conn.createStatement());
stmt.defineColumnType( 1, Types.VARCHAR );
ResultSet rst = stmt.executeQuery("select ad_finaltext from print_media" );
while( rst.next() )
{
String s = rst.getString( 1 );
System.out.println( s );
}
ノート:
LOBサイズが32767バイトより大きい場合、データは切り捨てられ、エラーはスローされません。ストリーミング・モードの場合:
OracleStatement stmt = (OracleStatement)(conn.createStatement());
stmt.defineColumnType( 1, Types.LONGVARCHAR );
ResultSet rst = stmt.executeQuery("select ad_finaltext from print_media" );
while(rs.next()) {
Reader reader = rs.getCharacterStream( 1 );
int data = 0;
data = reader.read();
while( -1 != data ){
System.out.print( (char)(data) );
data = reader.read();
}
reader.close();
}
ノート:
データ型をLONGVARCHAR
として指定すると、LOB全体を選択できます。定義タイプがLONGVARCHAR
ではなくVARCHAR
に設定されている場合、データは32kで切り捨てられます。
ad_finaltext
がCLOB
ではなくBLOB
列である場合、前述の例は、定義がLONGVARBINARY
型である場合に機能します。
...
OracleStatement stmt = (OracleStatement)conn.createStatement();
stmt.defineColumnType( 1, Types.INTEGER );
stmt.defineColumnType( 2, Types.LONGVARBINARY );
ResultSet rset = stmt.executeQuery("SELECT ID, LOBCOL FROM LOBTAB");
while(rset.next())
{
/* using getBytes() */
/*
byte[] b = rset.getBytes("LOBCOL");
System.out.println("ID: " + rset.getInt("ID") + " length: " + b.length);
*/
/* using getBinaryStream() */
InputStream byte_stream = rset.getBinaryStream("LOBCOL");
byte [] b = new byte [100000];
int b_len = byte_stream.read(b);
System.out.println("ID: " + rset.getInt("ID") + " length: " + b_len);
byte_stream.close();
}
...
親トピック: LOBのデータ・インタフェース