PostgreSQL中Blob字段的处理

Posted by Simon Dong on 2014-10-01

PostgreSQL存储大对象有两种方式,分别为普通的blob和oid对象类型。

  • 普通的bytea字段存储在表中,JDBC写入时,使用preparedStatement.setBinaryStream()即可。
  • oid对象存储的是一个类似外键的值,对象的数据存储在系统表中。

对OID对象的处理

服务器端

可在SQL语句中使用lo_create, lo_unlink,lo_import,lo_export等函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 来自JBPM4.4
CREATE TABLE jbpm4_lob
(
dbid_ bigint NOT NULL,
dbversion_ integer NOT NULL,
deployment_ bigint,
name_ text,
blob_value_ oid
};

insert into jbpm4_lob (dbid,blob_value_) values ('xxxx',lo_import('c:/tomcat7/temp/xxx.xml'));

-- 函数使用
select lo_create(-1); -- return OID of new, empty large object
select lo_create(4444); --attempts to create large object with oid 4444

select lo_unlink(4444); -- deletes large object with oid 444

select lo_export(jbpm4_lob.blob_value_, 'c:/tomcat7/temp/xxx.xml') from jbpm4_lob

客户端

  1. 对于文件来自与客户机(浏览器或者CS端),使用JDBC的方法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    private static void storeLargeObject(Connection conn,InputStream in) throws SQLException, IOException{
    //关闭自动提交
    conn.setAutoCommit(false);
    LargeObjectManager lobj = ((PGConnection)conn).getLargeObjectAPI();
    long oid = lobj.createLO(); //Create OID Object with Read/Write Mode
    LargeObject obj = lobj.open(oid,LargeObjectManager.WRITE);
    byte[] data = new byte[1024];
    int pos = 0,len = 0;
    while((len = in.read(data,0,1024)) > 0){
    obj.write(data,0,len);
    pos += len;
    }
    obj.close();
    PreparedStatement ps = conn.prepareStatement("insert into jbpm4_lob (dbid_,blob_value_) values (?,?)");
    ps.setLong(1, 1);
    ps.setLong(2, oid);
    ps.executeUpdate();
    ps.close();
    in.close();
    conn.commit();
    }
  2. 另一种方式,先将文件存储于服务器的临时目录中,然后使用lo_import的方式上传。

Hibernate说明

hibernate对bytea和bio类型的大对象处理无任何特别要求,hibernate默认创建bio对象,如果需要Hibernate创建bytea对象时,需要在实体类上注明:

1
2
3
@Lob
@Type(type="org.hibernate.type.BinaryType")
private byte[] data;

或者hbm.xml中

1
2
3
<property name="blob" type="org.hibernate.type.BinaryType">
<column name="BLOB_VALUE_" />
</property>