此InputStream非彼InputStream

作者: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);//保存附件   

保存成功,希望对大家有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄豆2019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值