关键:对于 Postgres,你必须在一个 SQL 事务里面访问大对象。尽管我们总是这样要求,但直到版本 6.5 我们才严格要求这样做。你应该带着一个输入参数 false 使用 setAutoCommit() 方法打开一个事务:Connection mycon; ... mycon.setAutoCommit(false); ... now use Large Objects
在JDBC里,标准的访问大对象的方法是使用 ResultSet 里的 getBinaryStream() 方法,和PreparedStatement 里的 setBinaryStream() 方法.这些方法把大对象表示成 Java 的流(stream),允许你用 java.io 和其他的包来操纵这些对象.
例如,假设你有一个包含一幅图象文件名的表,而且一个大对象包含这个图象:
create table images (imgname name,imgoid oid);要插入一幅图象,你可以:
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();现在,在这个例子里,setBinaryStream 从一个流里面把一定字节的数据转换到大对象里,然后把(大对象的) OID 存储到引用它的字段里.
检索一幅图象甚至更快(我在这里使用 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();这里你可以看到这里大对象是当做一个 InputStream (输入流)检索的.你还会注意到我们在处理结果的下一行之前关闭了流.这是 JDBC 规范的一部分,该规范指出任何返回的 InputStream 在调用 ResultSet.next() 或 ResultSet.close() 后都要被关闭.