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
客户端
对于文件来自与客户机(浏览器或者CS端),使用JDBC的方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21private 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();
}另一种方式,先将文件存储于服务器的临时目录中,然后使用lo_import的方式上传。
Hibernate说明
hibernate对bytea和bio类型的大对象处理无任何特别要求,hibernate默认创建bio对象,如果需要Hibernate创建bytea对象时,需要在实体类上注明:1
2
3
"org.hibernate.type.BinaryType") (type=
private byte[] data;
或者hbm.xml中1
2
3<property name="blob" type="org.hibernate.type.BinaryType">
<column name="BLOB_VALUE_" />
</property>