Postgresでは、(BLOBとしても知られる)ラージオブジェクトが、普通のSQLテーブルでは保存できないデータをデータベースに保存するために使われます。これらは特別なフォーマットでテーブルとは別に格納されて、テーブルからはOID値で参照されます。
Important: Postgresでは、ラージオブジェクトにアクセスするにはSQLのトランザクション内であることが必要です。パラメータをfalseとしてsetAutoCommit()を使うことで、トランザクションを開きます:
Connection mycon; ... mycon.setAutoCommit(false); ... // now use Large Objects
ラージオブジェクトを使うには2つの方法があります。1番目は、標準JDBCによる方法で、ここに記載します。もう1つの方法はこのドライバ独自のAPIを拡張したものを使用します。これはlibpqでのラージオブジェクトAPIをJavaで表現したもので、標準のものよりもより優れたラージオブジェクトへのアクセス手段を提供します。ドライバの内部では、この拡張を使用してラージオブジェクトのサポートを提供しています。
JDBCでのラージオブジェクトにアクセスする標準的な方法はResultSetのgetBinaryStream()メソッドとPreparedStatementのsetBinaryStream()メソッドを使用することです。これらのメソッドはラージオブジェクトをJavaのストリームとして表現しますので、java.ioパッケージなどを使用してラージオブジェクトを扱うことができるようになります。Example 8-2は、この使用方法を示します。
Example 8-2. JDBCのラージオブジェクトインタフェースの使用
例えば、次のように画像のファイル名と画像用のラージオブジェクトから成るテーブルがあるとします:
CREATE TABLE images (imgname text, 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仕様の一部です。