これらのクラスはLOBロケータを保持し、LOB値の読み込み、書き込みを行うためのメソッドを提供しています。
oracle.sql.BLOBクラス、oracle.sql.CLOBクラスを使用したLOBの操作例を以下に示します。
BLOBデータの読み込み
BLOBデータを読み込むには、まずSELECT文を実行してBLOBロケータを取得します。そして取得したBLOBロケータから入力ストリームを生成し、そこからBLOBデータを読み込んでいきます。
PreparedStatement pstmt = conn.prepareStatement( 'SELECT BLOB_VALUE FROM TABLEA WHERE ID = ?' ); pstmt.setInt( 1, 1 ); rs = pstmt.executeQuery(); if( rs.next() ){ BLOB blob = (( OracleResultSet ) rs ).getBLOB( 1 ); InputStream ins = blob.getBinaryStream(); bos = new ByteArrayOutputStream(); int len = -1; byte[] buffer = new byte[ 8192 ]; while( ( len = ins.read( buffer ) ) != -1 ){ bos.write( buffer, 0, len ); } blobValue = bos.toByteArray(); }
BLOBデータの書き込み
BLOBデータを書き込むには、まずSELECT文(FOR UPDATE付き)を実行してBLOBロケータを取得します。そして取得したBLOBロケータから出力ストリームを生成し、そこへBLOBデータを書き込んでいきます。
ByteArrayOutputStream bos = ・・・ PreparedStatement pstmt = conn.prepareStatement( 'SELECT BLOB_VALUE FROM TABLEA WHERE ID = ?' , ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE ); pstmt.setInt( 1, 1 ); rs = pstmt.executeQuery(); if( rs.next() ){ BLOB blob = (( OracleResultSet ) rs ).getBLOB( 1 ); OutputStream os = blob.getBinaryOutputStream(); os.write( bos.toByteArray() ); }
CLOBデータの読み込み
CLOBデータを読み込むには、まずSELECT文を実行してCLOBロケータを取得します。そして取得したCLOBロケータから入力ストリームを生成し、そこからCLOBデータを読み込んでいきます。
PreparedStatement pstmt = conn.prepareStatement( 'SELECT CLOB_VALUE FROM TABLE_A WHERE ID = ?' ); pstmt.setInt( 1, 1 ); rs = pstmt.executeQuery(); if( rs.next() ){ CLOB clob = (( OracleResultSet ) rs ).getCLOB( 1 ); Reader reader = clob.getCharacterStream(); int size = clob.getBufferSize(); char[] cbuffer = new char[size]; int length = -1; while ( ( length = reader.read( cbuffer ) ) != -1 ) clobValue = cbuffer.toString(); }
CLOBデータの書き込み
CLOBデータを書き込むには、まずSELECT文(FOR UPDATE付き)を実行してCLOBロケータを取得します。そして取得したCLOBロケータから出力ストリームを生成し、そこへCLOBデータを書き込んでいきます。
String clobValue = ・・・ PreparedStatement pstmt = conn.prepareStatement( 'SELECT CLOB_VALUE FROM TABLE_A WHERE ID = ?' , ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE ); pstmt.setInt( 1, 1 ); rs = pstmt.executeQuery(); if( rs.next() ){ clob = (( OracleResultSet ) rs ).getCLOB( 1 ); writer = clob.getCharacterOutputStream(); writer.write( clobValue ); writer.close(); }
と、こんな感じですが、いずれの場合もLOBロケータを取得し、LOBロケータに対するストリームを生成し、読み書きを行うという手順になっています。
そのため、JDBCドライバを使いながら、Oracle依存のコーディングとなってしまうのが難点です。
使用するRDBMSがOracleオンリーであれば問題ないですが、マルチRDBMS対応のアプリケーションを作成する場合、RDBMS間の差異を吸収・隠蔽するためにどうしても一工夫必要になってしまいます。
なんとかならないものですかね...
【関連エントリ】
[Oracle] LOBデータの基本的な扱い方 2004/12/03
[Oracle] JDBCによるLOBの操作方法 2004/12/06
[Oracle] LOBデータをファイルから直接登録する方法(その1) 2005/01/25
[Oracle] LOBデータをファイルから直接登録する方法(その2) 2005/01/27
[Oracle] LOBデータをファイルに直接出力する方法 2005/02/01
[Oracle] JavaでLOBデータを読み込む際の最適なバッファサイズは? 2005/02/02
[Oracle] LOB記憶特性 その1(STORAGE IN ROW) 2005/08/23
[Oracle] LOB記憶特性 その2(CHUNK) 2005/08/24