ラージオブジェクトの使用

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 仕様の一部です。