作者:huangshuidan@gmail.com 2009-6-16
前阶段在实现数据交换的时候遇到要实现这两个功能:
一、从表1读出Blob信息(用Hibernate方式),再写入表2(用JDBC方式)。
二、从表3读出Blob信息(用JDBC方式),再写入表4(用Hibernate方式)。
网上许多介绍JDBC、Hibernate存取blob都是单独介绍的,基本上没有说到Hibernate+JDBC结合使用,这里用到的的Hibernate+JDBC结合使用,那应该注意哪些问题呢,在这里我总结了一下。
功能1:
从表1读出blob转化成输入流代码段如下:
/**
* 读取BLOB转换成输入流InputStream
* @author huangshuidan@163.com 2009-5-20
* @param fileindex
* String-附件索引号
* @return
*/
public static InputStream readBlobToInputStream(String fileindex){
InputStream is=null;
Filestore filestore = FilestoreManager.doFindByFileIndex(fileindex);
if(null!=filestore){
BLOB blob=(BLOB)filestore.getContent();//转化成BLOB类型
try {
is=blob.getBinaryStream();
} catch (SQLException e) {
// TODO Auto-generated catch block
logger.error("获取输入流转化时出错啦!"+e.getMessage());
e.printStackTrace();
}
}
return is;
}
将blob写入到表2,通常用jdbc方式保存blob的时候,先插入一个空对象,再用for update方式锁定数据行。这里我调用一个自己写的方法:
doSQLUpdateBLOB(sql0, sql1, is, "content");//参数:增加语句,更新语句,输入流对象,blob列名。
sql0="inser tinto fujianxinxi(unid,projid,attachcode,attachname,filename,content) values('"+unid+"','"+projid+"','"+materialno+"','"+apasattr.getName()+"','"+attrFileName+"',empty_blob())";//插入一个空对象
sql1="select content from fujianxinxi where unid='"+unid+"' for update";//用for update方式锁定数据行
is:就是用上面方法readBlobToInputStream得到的输入流对象。
第四个参数:content对应表blob类型字段名称。
用jdbc来保存blob的代码段如下:
int a = jw.executeUpdate(sql0);//插入一个空对象BLOB
rs=jw.executeQuery(sql1);//以行的方式锁定
if (rs.next()) {
//使用oracle.sql.BLOB类
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(colBlobName);
//到数据库的输出流
OutputStream outStream = blob.getBinaryOutputStream();
//将输入流写到输出流
byte[] b = new byte[blob.getBufferSize()];
int len = 0;
while ( (len = fin.read(b)) != -1) {
outStream.write(b, 0, len);
}
//依次关闭
fin.close();
outStream.flush();
outStream.close();
}
直接从表1有读blob得到输入流,再用jdbc方式写入到表2。
功能2:
这个功能与上面刚好是反过来,先用jdbc读出blob,这时要注意的是
InputStream is=null;
BLOB blob = (BLOB)rs.getBlob(colBlobName);// colBlobName是表3blob字段的名称。
is = blob.getBinaryStream();
这时候要的是并不是InputStream ,如果说这时得到一个InputStream 对象is,用Hibernate.createBlob(is) 设置对象,调用Hibernate的保存方法,是错误的。刚开始我就犯了这个错误,只看到了Hibernate.createBlob(is),想当然地以为得到了一个InputStream 对象is就可以调用Hibernate的保存方法了,结果发现信息并没有写到blob字段中去。因为这里的InputStream 对象is并不是new FileInputStream(filename); 的对象。
这时候我们要关注的是这个方法: net.sf.hibernate.Hibernate.createBlob(byte[] arg0),所以我们要的是bytes。
代码段如下:
byte[] b = null;
ByteArrayOutputStream fos = new ByteArrayOutputStream();
rs = st.executeQuery(sql);
if(rs.next()){
//类型转化成BLOB
BLOB blob = (BLOB)rs.getBlob(colBlobName);
is = blob.getBinaryStream();
b = new byte[1024];
int borb = -1;
try {
while((borb = is.read(b))!= -1) {
fos.write(b, 0, borb);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
is.close();
}
这个方法要返回的是:fos.toByteArray();
fos.toByteArray()才是我们真正要的。
Filestore filestore = new Filestore();
filestore.setContent(Hibernate.createBlob(fos.toByteArray()));
FilestoreManager.doSave(filestore);//保存附件
保存成功,希望对大家有所帮助。