[SQL Server] JDBCによるtext、ntext、imageの操作方法(その2) | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

Javaからtext、ntext、image型のデータを操作する場合、getString()、setString()、getBytes()、setBytes()を利用すれば簡単ですが、この方法ではデータサイズが大きくなるにしたがってパフォーマンスが悪化します。

ある程度データサイズが大きい場合は、text、ntextであればsetCharacterStream()メソッド、getCharacterStream()メソッド、imageであればsetBinaryStream()メソッド、getBinaryStream()メソッドといった入出力ストリームを利用すれば効率よく操作することができます。

各メソッドを用いたtext、ntext、imageの操作例(一部抜粋)を以下に示します。
getCharacterStream()メソッドを利用したtextデータの読み込み
BufferedWriter bw = new BufferedWriter( new FileWriter( "C:\TEST.TXT" ) );
PreparedStatement pstmt 
  = con.prepareStatement( "SELECT TEXT_VALUE FROM TABLEA WHERE ID = ? " );
pstmt.setInt( 1, 1 );
rs = pstmt.executeQuery();
if( rs.next() ){
  BufferedReader br = new BufferedReader( rs.getCharacterStream( 1 ) );
  imageValue = rs.getBytes( 1 );
  char[] buffer = new char[ 8192 ];
  int length = -1;
  while( ( length = br.read( buffer, 0, 8192 ) ) != -1 ) {
    bw.write( buffer, 0, length );
  }
  br.close();
}
bw.close();
setCharacterStream()メソッドを利用したtextデータの書き込み
File file = new File( "C:\TEST.TXT" );
FileReader fr = new FileReader( file );
PreparedStatement pstmt 
  = con.prepareStatement( "INSERT INTO TABLEA (TEXT_VALUE) VALUES( ? )" );
pstmt.setCharacterStream( 1, fr, ( int )file.length() );
pstmt.execute();
fr.close();
getBinaryStream()メソッドを利用したimageデータの読み込み
FileOutputStream fos = new FileOutputStream( new File( "C:\TEST.JPG" ) );
PreparedStatement pstmt 
	= con.prepareStatement( "SELECT IMAGE_VALUE FROM TABLEA WHERE ID = ? " );
pstmt.setInt( 1, 1 );
rs = stmt.executeQuery();
if( rs.next() ){
  InputStream ins = rs.getBinaryStream( 1 );
  byte[] buffer = new byte[ 8192 ];
  int length = -1;
  while( ( length = ins.read( buffer , 0 , 8192 ) ) != -1 ) {
    fos.write( buffer , 0 , length );
  }
  ins.close();
}
fos.close();
setBinaryStream()メソッドを利用したimageデータの書き込み
File file = new File( "C:\TEST.JPG" );
FileInputStream fis = new FileInputStream( file );
PreparedStatement pstmt 
  = con.prepareStatement( "INSERT INTO TABLEA (IMAGE_VALUE) VALUES( ? )" );
pstmt.setBinaryStream( 1, fis , ( int )file.length() );
pstmt.execute();
fis.close();


ただし、上記の例のように入出力ストリームを利用する方法でも、サイズの大きなデータをStringやBytes[]といった変数に持つとメモリを圧迫します。


そのため、サイズの大きなデータはメモリ上に展開せず、直接ファイルに入出力するなどして負荷を軽減したほうがいいでしょう。




【関連エントリ】
[SQL Server] JDBCによるtext、ntext、imageの操作方法(その1) 2005/03/02
[SQL Server] JDBCによるtext、ntext、imageの操作方法(その2) 2005/03/03
[SQL Server] text型やimage型を読み込む際の最適なバッファサイズは? 2005/03/09
[SQL Server] imageデータをファイルから直接登録する方法 2005/03/15
[SQL Server] BULK INSERTステートメントによるデータのアップロード 2005/03/16
[SQL Server] imageデータをファイルに直接出力する。2005/03/17
[SQL Server] image型やtext型はテキストポインタを利用して取得したほうが速い 2005/08/04