在 Postgres里,大对象 (也称之为 BLOB)用于保存那些无法在通常 SQL 表里面保存的数据.它们是以一种特殊的格式存储在一个独立的 表里面的,然后用一个 OID 值从你自己的表里面引用.
Important: 对于 Postgres ,你必须在一个 SQL 事务里面访问大对象。 你应该带着一个输入参数false使用 setAutoCommit() 方法打开一个事务:
Connection mycon; ... mycon.setAutoCommit(false); ... // now use Large Objects
目前,你有两种使用大对象的方法.第一种是标准的 JDBC 方式,这个方式在这里有文档. 另一种,使用 PostgreSQL 对该(JDBC)API (编程接口)的扩展, 也是一种用于 Java 的 libpq 大对象 API 的形式, 提供了一种比标准方法更好的访问大对象的访问方法. 在系统内部,该驱动使用这种扩展来提供大对象支持.
在 JDBC里, 标准的访问大对象的方法是使用ResultSet里的 getBinaryStream()方法, 和 PreparedStatement 里的 setBinaryStream()方法. 这些方法把大对象表示成 Java 的流(stream), 允许你用java.io和其他的包来操纵这些对象. Example 8-2 演示了这个方法.
例如,假设你有一个包含一幅图象文件名的表,而且一个大对象包含这个图象:
CREATE TABLE images (imgname text, imgoid oid);
要插入一幅图象,你可以:
File file = new File("myimage.gif"); FileInputStream fis = new FileInputStream(file); PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)"); (1) ps.setString(1, file.getName()); ps.setBinaryStream(2, fis, file.length()); ps.executeUpdate(); ps.close(); fis.close();
检索一幅图象甚至更容易(我在这里使用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() 后都要被关闭.