↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

不受支持的版本: 7.1
历史版本PostgreSQL 7.1 已于 2006 年 4 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本手册首页。

8.5. 使用大对象 #

在 Postgres 中,大对象 (也称为 BLOB)用于存放数据库中无法存储在普通 SQL 表中的数据。它们以一种特殊格式存储在一个单独的表中, 并通过一个 OID 值从你自己的表中引用。

重要

对于 Postgres,你必须在一个 SQL 事务内访问大对象。你可以通过以 false 作为输入参数调用 setAutoCommit() 方法来打开一个事务:

Connection mycon;
...
mycon.setAutoCommit(false);
... // now use Large Objects

使用大对象有两种方法。第一种是标准的 JDBC 方式,这里介绍的就是它。另一种使用 PostgreSQL 对 API 的扩展,它把 libpq 的大对象 API 呈现给 Java,提供了比标准方式更好的 大对象访问能力。在内部,驱动正是使用该扩展来提供大对象 支持的。

在 JDBC 中,访问大对象的标准方式是使用 ResultSet 中的 getBinaryStream() 方法和 PreparedStatement 中的 setBinaryStream() 方法。这些方法让 大对象表现为一个 Java 流,使你可以使用 java.io 包和其他包来操纵该 对象。例 8.2 演示了这种 方式的用法。

例 8.2. 使用 JDBC 大对象接口

例如,假设你有一个表存储图像的文件名, 并且你有一个包含该图像本身的大对象:

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();

(1)

问号必须按字面出现。实际数据由后面的行 代入。

这里,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 都会被关闭。


提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。