Postgres では、( blobs としても知られる)ラージオブジェクト が、普通の SQL テーブルでは保存できないデータをデータベースに保存 するために使われます。これらはテーブルとインデックスの組合せとして 保存され、テーブルからは OID 値で参照されています。
さてここに、ラージオブジェクトを使用する方法を示します。1 番目は、 標準 JDBC による方法で、ここに記載します。他の 方法はこのドライバ独自の API を拡張したものを使用します。これは libpq でのラージオブジェクト API を Java で表し たもので、標準のものよりもより優れたラージオブジェクトへのアクセス 手段を提供します。ドライバの内部では、この拡張を使用してラージオブ ジェクトのサポートを提供しています。
JDBC でのラージオブジェクトにアクセスする標準的 な方法は ResultSet の getBinaryStream() メソッドと PreparedStatement の setBinaryStream() メソッドを使用することです。これらのメソッドはラ ージオブジェクトを Java のストリームとして表しますので、 java.io package などを使用してラージオブジェクトを扱うことができるよ うになります。
例えば、下のように画像のファイル名と画像用のラージオブジェクトから 成るテーブルがあるとします。
create table images (imgname name,imgoid oid);
画像を挿入する場合、次を行ないます。
File file = new File("myimage.gif"); FileInputStream fis = new FileInputStream(file); PreparedStatement ps = conn.prepareStatement("insert into images values (?,?)"); ps.setString(1,file.getName()); ps.setBinaryStream(2,fis,file.length()); ps.executeUpdate(); ps.close(); fis.close();
さてこの例では、setBinaryStream はストリーム経由でラージオブジェクトに 設定されたバイト数分転送し、その参照を保持するフィールドにその OID を保 存します。
画像を取り出すことはもっと簡単です。(ここでは PreparedStatement を 使っていますが、Statement でも同様に使うことができます。)
PreparedStatement ps = con.prepareStatement("select oid from images where name=?"); ps.setString(1,"myimage.gif"); ResultSet rs = ps.executeQuery(); if(rs!=null) { while(rs.next()) { InputStream is = rs.getBinaryInputStream(1); // use the stream in some way here is.close(); } rs.close(); } ps.close();
ここでは、ラージオブジェクトが InputStream として取り出されているこ とが判るでしょう。結果の次の行を処理する前にこのストリームを閉じてい ることにも注意して下さい。これは、ResultSet.next() または ResultSet.close() が呼び出される時に全ての InputStream から返される状 態は閉ざされるという JDBC 仕様の一部です。