已结束支持的版本: 6.4
历史版本。 PostgreSQL 6.4 已结束支持。 请参阅 当前版本手册.
56.10. 使用大对象
在 Postgres 中,大对象(也称为blob)用于存放数据库中无法存储在普通 SQL 表中的数据。它们以一个“表/索引”对的形式存储,并通过一个 OID 值从你自己的表中引用。
使用大对象有两种方法。第一种是标准的 JDBC 方式,这里介绍的就是它。另一种使用我们自己对 api 的扩展,它把 libpq 的大对象 API 呈现给 Java,提供了比标准方式更好的大对象访问能力。在内部,驱动正是使用该扩展来提供大对象支持的。
在 JDBC 中,访问它们的标准方式是使用 ResultSet 中的 getBinaryStream() 方法和 PreparedStatement 中的 setBinaryStream() 方法。这些方法让大对象表现为一个 Java 流,使你可以使用 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 规范的一部分,该规范规定,当调用 ResultSet.next() 或 ResultSet.close() 时,返回的任何 InputStream 都会被关闭。