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

In Postgres, large objects (also known as blobs) are used to hold data in the database that cannot be stored in a normal SQL table. They are stored as a Table/Index pair, and are refered to from your own tables, by an OID value.

Postgres では、( blobs としても知られる)ラージオブジェクト が、普通の SQL テーブルでは保存できないデータをデータベースに保存 するために使われます。これらはテーブルとインデックスの組合せとして 保存され、テーブルからは OID 値で参照されています。

Now, there are you methods of using Large Objects. The first is the standard JDBC way, and is documented here. The other, uses our own extension to the api, which presents the libpq large object API to Java, providing even better access to large objects than the standard. Internally, the driver uses the extension to provide large object support.

さてここに、ラージオブジェクトを使用する方法を示します。1 番目は、 標準 JDBC による方法で、ここに記載します。他の 方法はこのドライバ独自の API を拡張したものを使用します。これは libpq でのラージオブジェクト API を Java で表し たもので、標準のものよりもより優れたラージオブジェクトへのアクセス 手段を提供します。ドライバの内部では、この拡張を使用してラージオブ ジェクトのサポートを提供しています。

In JDBC, the standard way to access them is using the getBinaryStream() method in ResultSet, and setBinaryStream() method in PreparedStatement. These methods make the large object appear as a Java stream, allowing you to use the java.io package, and others, to manipulate the object.

JDBC でのラージオブジェクトにアクセスする標準的 な方法は ResultSet の getBinaryStream() メソッドと PreparedStatement の setBinaryStream() メソッドを使用することです。これらのメソッドはラ ージオブジェクトを Java のストリームとして表しますので、 java.io package などを使用してラージオブジェクトを扱うことができるよ うになります。

For example, suppose you have a table containing the file name of an image, and a large object containing that image:

例えば、下のように画像のファイル名と画像用のラージオブジェクトから 成るテーブルがあるとします。

create table images (imgname name,imgoid oid);

To insert an image, you would use:

画像を挿入する場合、次を行ないます。

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();

Now in this example, setBinaryStream transfers a set number of bytes from a stream into a large object, and stores the OID into the field holding a reference to it.

さてこの例では、setBinaryStream はストリーム経由でラージオブジェクトに 設定されたバイト数分転送し、その参照を保持するフィールドにその OID を保 存します。

Retrieving an image is even easier (I'm using PreparedStatement here, but Statement can equally be used):

画像を取り出すことはもっと簡単です。(ここでは 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();

Now here you can see where the Large Object is retrieved as an InputStream. You'll also notice that we close the stream before processing the next row in the result. This is part of the JDBC Specification, which states that any InputStream returned is closed when ResultSet.next() or ResultSet.close() is called.

ここでは、ラージオブジェクトが InputStream として取り出されているこ とが判るでしょう。結果の次の行を処理する前にこのストリームを閉じてい ることにも注意して下さい。これは、ResultSet.next() または ResultSet.close() が呼び出される時に全ての InputStream から返される状 態は閉ざされるという JDBC 仕様の一部です。