[pgsql-jp: 41175] Re: ご教授お願いします

take saitoh_takeshi @ ics.co.jp
2012年 8月 8日 (水) 08:52:49 JST


さいとうです。

At Tue, 7 Aug 2012 19:47:29 +0900 (JST),
<takart32 @ yahoo.co.jp> wrote:
> 
> さいとうさん
> 
> アドバイスありがとうございます。
> 
> > # typoはご容赦を
> > 
> > ByteArrayOutputStream zippedbaos = ...;
> > ByteArrayInputStream bais = new ...(zippedbaos.getBytes());
> > PreparedStatement pstmt = conn.preparedStatement("insert into hoge2 values (id, bin) values (?, ?)");
> > pstmt.setString(1, "xx");
> > pstmt.setBinaryStream(2, bais);
> > pstmt.executeUpdate();
> 
>  ⇒empty_blob()関数を使用しなくて良い方式もあるのですね。
>    貴重な情報ありがとうございます。
>    私の技量不足で下記処理についてうまく理解できませんでした。
>    大変恐縮なのですが「・・・」で省略している部分の処理を教えていただけないでしょうか?


At Tue, 7 Aug 2012 15:58:22 +0900 (JST),
<takart32 @ yahoo.co.jp> wrote:
...
> (1)新規レコードをinsertする。insert時にBLOBカラムは、empty_blob()関数で初期化する。
> (2)insertした新規レコードを、for update句を使用して、ロックを取得してselectする。
> (3)selectしたBLOBカラムのロケータから、BinaryOutputStreamを取得する。
> (4)取得したBLOBオブジェクトのOutputStreamをZip形式でinsertするので、ZipOutputStreamを作成。
> (5)ZipOutputStreamをObjectOutputStreamでラップする。
> (6)writeObjectでDBに書き込みを行う。

# ZipOutputStreamではなく、GZipOutputStreamではないですかね?


 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 GZipOutputStream gzo = new GZipOutputStream(baos);
 ObjectOutputStream  oos = new ObjectOutputStream(gzo);
 ... // ここは、高橋さんのやりたい処理
 // oos.writeObject(obj); とか
 oos.close();
 gzo.close();
 baos.close();

 ByteArrayInputStream bais = new ByteArrayInputStream(baos.getByteArray());
 PreparedStatement pstmt = conn.preparedStatement("insert into hoge2 (id, bin) values (?, ?)");
 pstmt.setString(1, "xx");
 pstmt.setBinaryStream(2, bais);
 pstmt.executeUpdate();
 // bais.close(); // 必要なような、不要なような...?


あるバージョン以前のOracleでblobを扱おうとすると、empty_blob()関数を使っ
て初期化して、insertして、ロックして、updateして、....、という手順が必
要だったようです。けれど、PostgreSQLやあるバージョン以降のOracleでblob
を扱うときは、blobだからといって特別なことをする必要はなく、文字列なら
StringをPreparedStatement#setString()でセットするように、blobなら
InputStreamをPreparedStatement#setBinaryStream()でセットすればいいよう
です、ということでした。

試してはいませんが、ByteArrayInputStreamは不要かもしれません。
PreparedStatement#setBytes()でいいのかもしれません。

 PreparedStatement pstmt = conn.preparedStatement("insert into hoge2 (id, bin) values (?, ?)");
 pstmt.setString(1, "xx");
 pstmt.setBytes(2, baos.getByteArray());
 pstmt.executeUpdate();


また、巨大なデータを扱うなどの理由で、メモリ使用量が心配なら、
ByteArrayOutputStream / ByteArrayInputStreamではなく、
FileyOutputStream / FileInputStreamを使う必要があるかもしれませんね。




pgsql-jp メーリングリストの案内