`
shinestarwang
  • 浏览: 41650 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

java上传保存图片到数据库

阅读更多
《摘抄1》
PostgreSQL 7.4 文档
Prev Fast Backward Chapter 31. JDBC 接口 Fast Forward Next
31.7. 存储二进制数据

PostgreSQL 提供两种不同的方法存储二进制数据。 二进制数据可以使用二进制数据类型 bytea存储在表中,或者使用大对象 特性,该特性以一种特殊的格式将二进制数据存储在一个独立的表中, 然后通过在你的表中保存一个指向该表的类型为 oid 的数值来引用它。

为了判断那种方法比较合适,你必须理解每种方法的局限。 bytea 数据类型并不适合存储非常大数量的二进制数据。 虽然类型为 bytea 的字段可以存储最多 1G 字节的二进制数据, 但是这样它会要求数量巨大的内存来处理这样巨大的数值。存储二进制的大对象的方法更适合存储非常大的数值, 但也有自己的局限。特别是删除一个包含大对象引用的行并未删除大对象。 删除大对象是一个需要执行的独立的操作。大对象还有一些安全性的问题, 因为任何联接到数据库的人都可以查看或者更改大对象,即使他们没有查看/更新包含大对象引用的行的权限也一样。

版本 7.2 是第一个支持 bytea 类型的 JDBC 驱动版本。在 7.2 中引入的这个功能同时也引入了一个和以往的版本不同的行为。自 7.2 以来,方法 getBytes(), setBytes(), getBinaryStream() 和 setBinaryStream() 操作 bytea 类型。 在 7.1 和更早的版本里这些方法操作和 OID 类型关联的大对象。 我们可以通过在 Connection 上设置 compatible 属性为数值 7.1 来获取旧的 7.1 的行为。

要使用 bytea 数据类型你只需要使用 getBytes(),setBytes(), getBinaryStream(),或者 setBinaryStream() 方法。

要使用大对象的功能,你可以使用 PostgreSQL JDBC 驱动提供的 LargeObject 类,或者使用 getBLOB() 和 setBLOB() 方法。

    Important: 你必须在 一次 SQL 事务内访问大对象。你可以通过 调用 setAutoCommit(false) 打开一个事务。

    注意: 在将来的 JDBC 驱动中, getBLOB() 和 setBLOB() 方法可能不再操作大对象,而是将处理 bytea 数据类型。 因此如果你要用大对象,我们建议你使用 LargeObject API。

Example 31-8 包含一些有关如何用 PostgreSQL JDBC 驱动处理二进制数据的例子。

Example 31-8. 在 JDBC 里处理二进制数据例子

比如,假设你有一个表包含一幅图像和它的文件名, 并且你还想在 bytea 字段里存储图像∶

CREATE TABLE images (imgname text, img bytea);

要插入一幅图象,你可以:

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() 把来自一个流的 一些数目的字节转换成类型 bytea 的字段。 如果图像的内容已经放在 byte[] 里面了, 那么你也可以用 setBytes() 方法干这件事。

检索一幅图象甚至更容易(我在这里使用PreparedStatement,当然用Statement也是一样的):

PreparedStatement ps = con.prepareStatement("SELECT img FROM images WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null) {
        while (rs.next()) {
                byte[] imgBytes = rs.getBytes(1);
                // 从这开始使用数据
                }
        rs.close();
}
ps.close();

这里的二进制数据是以 byte[] 形式检索的。你也可以使用一个 InputStream。

另外你可能会需要存储一个非常大的文件,因此希望使用 LargeObject 类存储该文件∶

CREATE TABLE imageslo (imgname text, imgOID oid);

要插入一个图像,你可以用∶

// 所有大对象 API 调用都必须在一次事务中
conn.setAutoCommit(false);

// 获取大对象管理器以便进行操作
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();

//创建一个新的大对象
int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);

//打开一个大对象进行写
LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);

// 现在打开文件
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);

// 从文件拷贝数据到大对象
byte buf[] = new byte[2048];
int s, tl = 0;
while ((s = fis.read(buf, 0, 2048)) > 0){
      obj.write(buf, 0, s);
      tl += s;
}

// 关闭大对象
obj.close();

//现在向 imgeslo 插入行
PreparedStatement ps = conn.prepareStatement("INSERT INTO imageslO VALUES (?,?)");
ps.setString(1, file.getName());
ps.setInt(2, oid);
ps.executeUpdate();
ps.close();
fis.close();

从大对象中检索图像∶

// 所有 LargeObject API 调用都必须在一个事务里
conn.setAutoCommit(false);

// 获取大对象管理器以便进行操作
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();

PreparedStatement ps = con.prepareStatement("SELECT imgoid FROM imageslO WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null) {
    while (rs.next()) {
      //打开大对象读
      int oid = rs.getInt(1);
      LargeObject obj = lobj.open(oid, LargeObjectManager.READ);

      //读取数据
      byte buf[] = new byte[obj.size()];
      obj.read(buf, 0, obj.size());
      //在这里对读取的数据做些处理

      // 关闭对象
      obj.close();
    }
    rs.close();
}
ps.close();

Prev Home Next
创建和更改数据库对象 Up PostgreSQL 对 JDBC API的扩展

《摘抄2》
postgreSQL中怎样建个带图片字段的表啊?
postgreSQL中怎样建个带图片字段的表啊?
是不是这样啊:
create table test(
id int4 not null,
name varchar(10) not null,
tupian BLOB,
primary key(id)
);
如不是那应该是怎么建啊?
zug 发表于 2004-02-25 08:45

postgreSQL中怎样建个带图片字段的表啊?
引用
原帖由 "marszxy" 发表:
postgreSQL中怎样建个带图片字段的表啊?
是不是这样啊:
create table test(
id int4 not null,
name varchar(10) not null,
tupian BLOB,
primary key(id)
);
如不是那应该是怎么建啊?


BLOB在PG中没有。可以用三种方式存图片
1.使用大对象
create table test(
id int4 not null,
name varchar(10) not null,
tupian oid,
primary key(id)
);

2.使用Text字段将二进制图片用BASE64编码存为字符串
create table test(
id int4 not null,
name varchar(10) not null,
tupian text,
primary key(id)
);

3.用二进制数组bytea
create table test(
id int4 not null,
name varchar(10) not null,
tupian bytea,
primary key(id)
);

以上三种方式(第一种属过时的方法,且操作稍复杂)都可以存图片
或其它任何格式的数据长度好象是2G的限制。
netkiller 发表于 2004-02-25 15:36

postgreSQL中怎样建个带图片字段的表啊?
TEXT BASE64 那个,不太好.
BASE64后.文件会增大很多..
还有编码/解码.这个过程也浪费资源..

你看看这个..
http://www.pgsqldb.org/pgsqldoc-cvs/jdbc-binary-data.html
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics