《摘抄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
分享到:
相关推荐
java实现上传图片存入到数据库,只能用炫酷来形容,感兴趣就下载看看吧
基于SSM(Spring+SpringMvc+Mybatis)框架的图片上传并保存到数据库中与回显的案例
使用上传功能获取路径(我这边的是直接指定的,一般是从页面层获取的),然后传到dao层 然后通过dao层将二进制流写到数据库中(附上数据库); 点击下载功能,从数据库中获取二进制流,然后将二进制流转换为...
使用Spring Boot上传文件的简单Demo
本地图片使用二进制流存储到MySQL中,然后响应前端的传参,查询后可以显示在HEML网页中,相当于图片的简单上传和显示
图片BASE64加密保存到数据库Blob类型中(放入数据库,并取出生成图片),完整的demo例子,可运行。
servlet 上传文件流保存到数据库
Javaweb应用图片文件上传并预览,Tomcat服务器存储至磁盘,数据库mysql存储其图片路径
用于图片上传至服务器下的文件夹里面,并且把文件路径加入数据库,数据库采用MSSQL2000
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request....
本人写的上传下载demo 一会儿博客里面会有提到 亲们可以先看看然后在下载
本例采用Java-Web技术,采用mvc设计模式,使用c3p0数据库连接池,实现图片上传到服务器并保存到数据库中
里面是完整的案例 自己项目里面摘出来的 项目亲测有效
通过base64上传图片到服务器并读取图片。上传的图片一般都会保存在服务器的某一个目录里面,这次的笔记则是对着图片的上传和读取的。
实现了上传图片并保存到数据库,然后可以在页面上显示。
网上现有例子大都是上传本地文件到数据库,该例子可以jsp上传文件并保存到数据库,读取显示;但是最后需要用户自己删除服务器端文件。
处理前后台图片旋转问题,前台处理旋转图片展示问题。后台处理旋转图片处理后保存到服务器和数据库问题。
后续更新成base64数据保存到数据库,直接base64转换成图片保存在服务器,数据库存储相关信息,下载或者查看的时候直接调用相对路径的文件即可。 毕竟base64的数据保存到数据库太影响查询了。另外在存储文件的时候...
该资源是自己做的(后台是java,页面是jsp,用了Jcrop插件裁剪图片),能实现上传本地图片,预览在页面上并根据用户的需求进行任意大小的裁剪,最后将裁剪后的图片进行展示。整个过程会把图片的名字插入数据库字段;...
毕业设计,基于SpringBoot+Vue+MySql开发的美妆商城系统,内含Java完整源代码,数据库脚本,前台商城,后台管理 ...4、图片上传问题,图上上传后 保存到项目的静态资源下了。src/main/resources/static/file