- PR -

PostgreSQLにJavaオブジェクトを保存する方法

1
投稿者投稿内容
kaji
会議室デビュー日: 2004/05/24
投稿数: 4
投稿日時: 2004-05-24 14:21
ある検索システムを作っているのですが、検索時間短縮のため、
検索に利用できるJavaのオブジェクトを、直列化して
PostgreSQLに保存したいと考えています。

以下のURLから、setObjectメソッドでストアできると言うことは分かったのですが、
http://java.sun.com/j2se/1.3/ja/docs/ja/guide/jdbc/spec2/jdbc2.1.frame7.html

PostgreSQLでのテーブル定義の際、データの型を何にしたらよいのかが分かりません。

保存したいJavaのオブジェクトはSerializableを
実装済みで、ファイルへの出力は正常に行うことができます。

ご存知の方がいましたら、ご教授ください。

--
環境は
Windows XP
J2SDK1.4.1_01
PostgreSQL 7.4.1-3
です。
Odakaz
ベテラン
会議室デビュー日: 2004/05/24
投稿数: 70
投稿日時: 2004-05-24 17:19
BLOBじゃないですかね
taro
ぬし
会議室デビュー日: 2003/10/20
投稿数: 316
投稿日時: 2004-05-24 17:37
確認していませんが、byteaではないでしょうか?
http://www.postgresql.jp/document/pg721doc/user/datatype-binary.html
kaji
会議室デビュー日: 2004/05/24
投稿数: 4
投稿日時: 2004-05-24 18:01
回答ありがとうございます。

BLOBでテーブルを定義しようとしたところエラーが出ましたが、
byteaでは定義することができました。

test=# create table test(key text,object bytea);
CREATE TABLE

しかし、実際にJavaオブジェクトをDBに入れるときに怒られます。
実際にVectorを入れてみようとやってみたプログラムが以下のものです。

--
Vector v=new Vector();
v.add("hogehoge");
v.add("aheahe");

String statement="insert into test(key,object) values ('person',?)";
PreparedStatement ps = _con.prepareStatement(statement);
ps.setObject(1,v);
ps.execute();

--
エラーメッセージはsetObjectの部分で表示されました。以下のとおりです。
--
The table for java.util.Vector is not in the database. Contact the DBA, as the database is in an inconsistent state.

--

PostgreSQLのほうのデータ型をbytea以外のものにして(textなど)試してみても、
同じエクセプションが表示されるので、データ型の問題ではないのかもしれないです。

対処法をご存知の方は教えていただきたいと思います。
よろしくお願いします。
tanabo
常連さん
会議室デビュー日: 2003/04/24
投稿数: 34
投稿日時: 2004-05-24 18:19
byteaにバイナリをINSERTするには、setBinaryStreamメソッドを使います。

以下のサイトを参考にしてください。

http://www.postgresql.jp/document/pg742doc/html/jdbc-binary-data.html#JDBC-BINARY-DATA-EXAMPLE
kaji
会議室デビュー日: 2004/05/24
投稿数: 4
投稿日時: 2004-05-24 19:22
返信ありがとうございます。
setBinaryStreamを使ってみたところオブジェクトの保存、取出しが
正常にできました。

しかし、作ったプログラムはDBに入れる際に一度一時ファイルに保存するところがスマートでないかなと思っています。

ファイルに一度出力してからFileInputStreamを取得する以外に、
保存したいObjectのInputStreamを取得する方法は無いでしょうか?

ご存知の方いらっしゃいましたら、お教えていただきたいです。よろしくお願いします。



以下は作ったソースです。

保存
---

Vector v=new Vector();
v.add("hogehoge");
v.add("aheahe");

File outf=new File("tmp.dat");
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(outf));
out.writeObject(v);
out.flush();
out.close();

File inf=new File("tmp.dat");
FileInputStream fis=new FileInputStream(inf);
String statement="insert into test(key,object) values ('person',?)";
PreparedStatement ps = _con.prepareStatement(statement);
ps.setBinaryStream(1, fis,(int)inf.length());
ps.executeUpdate();
ps.close();
fis.close();


--
取り出し
--
String statement ="select object from test where key='person'";
PreparedStatement ps = _con.prepareStatement(statement);

ResultSet rs = ps.executeQuery();
if (rs != null) {
while (rs.next()) {
InputStream is=rs.getBinaryStream("object");
ObjectInputStream ois=new ObjectInputStream(is);

Vector v=(Vector)ois.readObject();
System.out.println("vector:"+v);
}
rs.close();
}
ps.close();

--


じゃばら
会議室デビュー日: 2004/05/24
投稿数: 10
お住まい・勤務地: 福岡
投稿日時: 2004-05-24 21:10
初めまして、じゃばらと申します。

たしかに、一時ファイルを使うのは少しおおげさかもしれませんね。
そこでメモリを使ってみるというのはどうでしょう。
コードはこんな感じになります。

ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
objOut.writeObject(v);
ByteArrayInputStream byteIn =
    new ByteArrayInputStream(byteOut.toByteArray());
ps.setBinaryStream(1, byteIn, byteOut.size());

動作確認はしていませんが・・・


[ メッセージ編集済み 編集者: じゃばら 編集日時 2004-05-24 21:12 ]
kaji
会議室デビュー日: 2004/05/24
投稿数: 4
投稿日時: 2004-05-25 11:38
じゃばら様、返信ありがとうございます。

ByteArrayOutputStreamとByteArrayInputStreamには気づきませんでした^^;
実際にやってみたら見事に動作しました。

これでずいぶんプログラムがすっきりしました。
どうもありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)