如何将对象持久化到数据库中BLOB

 我来答
就烦条0o
2017-12-24 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46492
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
对象持久化,也就是可以把这个对象永远的保存起来,这里的保存不仅是对象本身,还包括他的属性和所依赖的其他类。通常,对象可以持久化到文件或者是数据库中。我这里只介绍如何将对象存储到数据库中。恰巧Oracle数据库为我们提供了这样的方便。
在Oracle中,有一种blog的字段类型,它是用来存储大量的二进制数据的。我们就利用这个字段去存储对象信息。
首先建立一个测试表:
create table TESTBLOB
(
NAME VARCHAR2(50) not null,
CONTENT BLOB not null,
ID NUMBER(8) not null
)alter table TESTBLOB
add constraint IDFORTEST primary key (ID);
只用三个字段,其中id是属性,content是我们要存储对象的字段。
先来看看我们要存入的对象:
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class TestObject implements Serializable {
private static final long serialVersionUID = 4558876142427402513L;
/**
* @param args
*/
private String name;
private String password;
private Date date;
private List<City> cityList;
public List<City> getCityList() {
return cityList;
}
public void setCityList(List<City> cityList) {
this.cityList = cityList;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
记得要实现Serializable接口,可以看到这是一个包含了string,date,和list类型的对象,为了给测试增加复杂度,我们的list是另外一个对象(city)的list,如下:
import java.io.Serializable;
public class City implements Serializable{
private static final long serialVersionUID = 4558876127402513L;
private String name;
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
City对象包括了城市名称和区号。下面是主要的应用了。
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import oracle.sql.BLOB;
public class Test {
public static void main(String[] args) {
//创建测试用对象
City beijing = new City();
beijing.setName("北京");
beijing.setCode("010");
City shanghai = new City();
shanghai.setName("上海");
shanghai.setCode("020");
City tianjin = new City();
tianjin.setName("天津");
tianjin.setCode("021");
List<City> cityList = new ArrayList<City>();
cityList.add(beijing);
cityList.add(shanghai);
cityList.add(tianjin);
TestObject obj = new TestObject();
obj.setName("yangsq");
obj.setPassword("111");
obj.setDate(new Date());
obj.setCityList(cityList);
try{
//将对象存入blob字段
ByteArrayOutputStream byteOut=new ByteArrayOutputStream();
ObjectOutputStream outObj=new ObjectOutputStream(byteOut);
outObj.writeObject(obj) ;
final byte[] objbytes=byteOut.toByteArray();
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(
"jdbc:oracle:thin:@***.***.***.***:1521:****", "yangsq", "yangsq");
con.setAutoCommit(false);
Statement st = con.createStatement();
st.executeUpdate("insert into TESTBLOB (ID, NAME, CONTENT) values (1, 'test1', empty_blob())");
ResultSet rs = st.executeQuery("select CONTENT from TESTBLOB where ID=1 for update");
if (rs.next()) {
BLOB blob = (BLOB) rs.getBlob("CONTENT");
OutputStream outStream = blob.getBinaryOutputStream();
outStream.write(objbytes, 0, objbytes.length);
outStream.flush();
outStream.close();
}
byteOut.close();
outObj.close();
con.commit();
//取出blob字段中的对象,并恢复
rs = st.executeQuery("select CONTENT from TESTBLOB where ID=1");
BLOB inblob = null;
if (rs.next()) {
inblob = (BLOB) rs.getBlob("CONTENT");
}
InputStream is = inblob.getBinaryStream();
BufferedInputStream input = new BufferedInputStream(is);
byte[] buff = new byte[inblob.getBufferSize()];
while(-1 != (input.read(buff, 0, buff.length)));
ObjectInputStream in =
new ObjectInputStream(
new ByteArrayInputStream(
buff));
TestObject w3 = (TestObject)in.readObject();
System.out.println(w3.getName());
System.out.println(w3.getPassword());
System.out.println(w3.getDate());
List<City> list = w3.getCityList();
for(City city : list){
System.out.println(city.getName() + " " + city.getCode());
}
st.close();
con.close();
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}
代码的蓝色部分创建了要存储的对象。再看红色的对象写入部分,它首先把对象转化成二进制流的形式。对于blob字段,我们不能简单的在insert时插入,实际上,insert时,对于blob字段,只能先插入一个空的blob对象empty_blob(),然后再进行"select CONTENT from TESTBLOB where ID=1 for update"对blob字段进行更新。返回后,我们只要把对象的二进制流写入即可。
OutputStream outStream = blob.getBinaryOutputStream();
outStream.write(objbytes, 0, objbytes.length);
需要注意的是,上述步骤必须设置con.setAutoCommit(false),否则oracle会抛出异常。
接下来,绿色的代码是读取数据库中blob字段的对象,并恢复。我们要知道的是,所有对blob字段的操作都是二进制的,即插入时是二进制流,读出时也是二进制流。然后用io修饰器(ObjectInputStream)去修饰。以前学习java时,感觉它的io好繁琐啊,现在感觉还真是各有其用。下面是测试的输出结果。
yangsq
111
Tue Mar 27 12:11:28 CST 2007
北京 010
上海 020
天津 021
需要说明一下,buff的size一定要足够大,否则将抛出异常。在这里,我使用的是inblob.getBufferSize()来设置buff的size,这并不是一种好的方法,因为一般inblob.getBufferSize()都是32768,很可能出现异常,所以这个size最好自己设置,或系统运行时刻设置(幸好java提供数组长度的运行时刻设置)。
折柳成萌
高粉答主

2017-12-25 · 繁杂信息太多,你要学会辨别
知道顶级答主
回答量:4.4万
采纳率:96%
帮助的人:6304万
展开全部
使用PL/SQL从数据库中读取BLOB对象:
1.首先,确认现有对象

SQL> col fdesc for a30
SQL> select fid,fname,fdesc from eygle_blob;

FID FNAME FDESC
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式