hibernate3中对blob的处理

在存储图片、可执行文件等二进制信息时(当然直接放在文件系统上也行),BLOB 数据就派上用场了。本文无太多深度可言,能为大家在开发过程中提供参考足亦!
Hibernate 与 SQL Server BLOB

 

BLOB 数据在 SQL Server 数据库中主要由 IMAGE 类型体现,最大容量为 2GB。其存储方式不同于普通的数据类型,对于普通类型的数据系统直接在用户定义的字段上存储数据值,而对于 IMAGE 类型数据,系统开辟新的存储页面来存放这些数据,表中 IMAGE 类型数据字段存放的仅是一个 16 字节的指针,该指针指向存放该条记录的 IMAGE 数据的页面。如果你对 Hibernate 还不熟息,请看这里。

 


新建名为 “BLOB_TEST” 的表,字段分别是 INT 类型的 “ID” 和 IMAGE 类型的 “MYBLOB”。从文件系统读取 “sample.jpg” 并转换成字节数组再放进 BlobTest 对象实例。写入程序如下:

import java.io.*;

 

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

 

import bo.*;

 

public class Tester {

 

 public void DoTest() {
  InputStream in = null;
  BlobTest blobTest = null;
  Configuration cfg = null;
  SessionFactory sessions = null;
  Session session = null;
  Transaction tx = null;
  try {
   //begin InputStream
   in = new FileInputStream("d:/sample.jpg");
   byte[] b = new byte[in.available()];
   in.read(b);
   in.close();

 

   //begin BlobTest
   blobTest = new BlobTest();
   blobTest.setMyblob(b);

 

   //begin Hibernate Session
   cfg = new Configuration().configure();
   sessions = cfg.buildSessionFactory();
   session = sessions.openSession();
   tx = session.beginTransaction();
   session.save(blobTest);
   tx.commit();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    session.close();
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
 }
}


取出程序如下:

import java.io.*;

 

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

 

import bo.*;

 

public class Tester {

 

 public void DoTest() {
  OutputStream out = null;
  BlobTest blobTest = null;
  Configuration cfg = null;
  SessionFactory sessions = null;
  Session session = null;
  try {
   //begin Hibernate Session
   cfg = new Configuration().configure();
   sessions = cfg.buildSessionFactory();
   session = sessions.openSession();

 

   //begin BlobTest
   blobTest = new BlobTest();
   blobTest = (BlobTest) session.load(BlobTest.class, new Integer(23));

 

   //begin OutputStream
   out = new FileOutputStream("d:/sample.jpg");
   out.write(blobTest.getMyblob());
   out.flush();
   out.close();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    session.close();
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
 }
}
 
Hibernate 与 MySQL BLOB

 

    MySQL 中的 BLOB 数据由四种类型体现,分别是 TINYBLOB 其容量为 256 字节、BLOB 其容量为 64KB、MEDIUMBLOB 其容量为 16MB、LONGBLOB 其容量为 4GB。


新建名为 “BLOB_TEST” 的表,字段分别是 INTEGER 类型的 “ID” 和 MEDIUMBLOB 类型的 “MYBLOB”。从文件系统读取 “sample.jpg” 并转换成字节数组再放进 BlobTest 对象实例。写入、取出程序和上面的 SQL Server 一样。
Hibernate 与 Oracle BLOB

 

    为了不使用 “for update” 锁住数据库,遂打算让 Oracle LONG RAW 类型保存大对象,最大容量 2GB。经过测试后发现,直接写 JDBC 代码可以保存,但 Hibernate 只能保存 4K 大小内容,换成 Hibernate 3.0 beta3 也未能成功。偶然的机会在邮件列表上发现这是 JDBC Driver 的问题,换成 Oracle 10g 的驱动后问题解决。


新建名为 “BLOB_TEST” 的表,字段分别是 NUMBER 类型的 “ID” 和 LONG RAW 类型的 “MYBLOB”。从文件系统读取 “sample.jpg” 并转换成字节数组再放进 BlobTest 对象实例。写入、取出程序和 SQL Server 一样。


如果你一定要用 Oracle BLOB 类型,接着往下看:

 

    Hibernate 处理 Oracle BLOB 类型较特殊,从文件系统读取 “sample.jpg” 放进 BlobTest 对象实例的是 java.sql.Blob 类型,而不是字节数组。

 

import java.io.*;

 

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
import oracle.sql.*;

 

import bo.*;

 

public class Tester {

 

 public void DoTest() {
  BLOB blob = null;
  InputStream in = null;
  OutputStream out = null;
  BlobTest blobTest = null;
  Configuration cfg = null;
  SessionFactory sessions = null;
  Session session = null;
  Transaction tx = null;
  try {
   //begin InputStream
   in = new FileInputStream("d:/sample.jpg");
   byte[] b = new byte[in.available()];
   in.read(b);
   in.close();
  
   //begin BlobTest
   blobTest = new BlobTest();
   blobTest.setMyblob(BLOB.empty_lob());
  
   //begin Hibernate Session
   cfg = new Configuration().configure();
   sessions = cfg.buildSessionFactory();
   session = sessions.openSession();
   tx = session.beginTransaction();
   session.save(blobTest);
   session.flush();
   session.refresh(blobTest, LockMode.UPGRADE);
   blob = (BLOB) blobTest.getMyblob();
   out = blob.getBinaryOutputStream();
   out.write(b);
   out.close();
   session.flush();
   tx.commit();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    session.close();
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
 }
}
 
取出程序和其他两种数据库操作几乎一样。
 
iBATIS SQL Maps 与 SQL Server BLOB

 

    建表过程和 Hibernate 操作 SQL Server 一样,如果你对 iBATIS SQL Maps 还不熟息,请看这里。


映射文件如下:

 

<?xml version="1.0" encoding="UTF-8"?>

 

<!DOCTYPE sqlMap
    PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    " http://www.ibatis.com/dtd/sql-map-2.dtd">

 

<sqlMap>

 

    <insert id="insertBlob" parameterClass="bo.BlobTest">
      <![CDATA[
        insert into blob_test (myblob) values (#myblob#)
      ]]>
      <selectKey resultClass="java.lang.Integer" keyProperty="id">
        <![CDATA[
          SELECT @@IDENTITY AS ID
        ]]>
      </selectKey>
    </insert>

 

    <resultMap id="get-blob-result" class="bo.BlobTest">
      <result property="id" column="id"/>
      <result property="myblob" column="myblob"/>
    </resultMap>

 

    <select id="getBlob" resultMap="get-blob-result" parameterClass="bo.BlobTest">
      <![CDATA[
        select * from blob_test where id=#id#
      ]]>
    </select>
       
</sqlMap>
 
写入程序如下:

import java.io.*;

 

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

 

import bo.*;

 

public class Tester {

 

 public void DoTest() {
  byte[] b=null;
  Reader reader = null;
  InputStream in = null;
  BlobTest blobTest = null;
  SqlMapClient sqlMap = null;
  String resource = "SqlMapConfig.xml";
  try {
   //begin InputStream
   in = new FileInputStream("d:/sample.jpg");
   b = new byte[in.available()];
   in.read(b);
   in.close();

 

   //begin BlobTest
   blobTest = new BlobTest();
   blobTest.setMyblob(b);

 

   //begin SqlMapClient
   reader = Resources.getResourceAsReader(resource);
   sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
   sqlMap.startTransaction();
   sqlMap.insert("insertBlob", blobTest);
   sqlMap.commitTransaction();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    sqlMap.endTransaction();
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
 }
}
 
取出程序如下:
  import java.io.*;

 

import com.ibatis.sqlmap.client.*;
import com.ibatis.common.resources.*;

 

import bo.*;

 

public class Tester {

 

 public void DoTest() {
  Reader reader = null;
  OutputStream out = null;
  BlobTest blobTest = null;
  SqlMapClient sqlMap = null;
  String resource = "SqlMapConfig.xml";
  try {
   //begin BlobTest
   blobTest = new BlobTest();
   blobTest.setId(new Integer(21));

 

   //begin SqlMapClient
   reader = Resources.getResourceAsReader(resource);
   sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
   blobTest = (BlobTest) sqlMap.queryForObject("getBlob", blobTest);

 

   //begin OutputStream
   out = new FileOutputStream("d:/sample.jpg");
   out.write(blobTest.getMyblob());
   out.close();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    sqlMap.endTransaction();
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
 }
}


iBATIS SQL Maps 与 MySQL BLOB

 

    这个主题很简单,需要注意映射文件 insert 元素主键生成方式,写入、取出程序和上面的 SQL Server 一样:

 

    <insert id="insertBlob" parameterClass="bo.BlobTest">
      <![CDATA[
        insert into blob_test (myblob) values (#myblob#)
      ]]>
      <selectKey resultClass="java.lang.Integer" keyProperty="id">
    <![CDATA[
          select last_insert_id();
    ]]>
      </selectKey>
  </insert> 
 
iBATIS SQL Maps 与 Oracle BLOB

 

    使用 Oracle LONG RAW 类型,注意映射文件 insert 元素主键生成方式,写入、取出程序和上面的 SQL Server 一样:

 

    <insert id="insertBlob" parameterClass="bo.BlobTest">
      <selectKey resultClass="int" keyProperty="id">
        <![CDATA[
          select hibernate_sequence.nextval from dual
        ]]>
      </selectKey>
      <![CDATA[
        insert into blob_test (id,myblob) values (#id#,#myblob#)
      ]]>
    </insert>
 
如果你一定要用 Oracle BLOB 类型,接着往下看:

 

    在 iBATIS 2.0.9 以前,处理 Oracle BLOB 类型相当麻烦,要自己实现TypeHandlerCallback 接口。iBATIS 2.0.9 提供了 BlobTypeHandlerCallback 实现类,写入、取出程序和上面的 SQL Server 一样。只是映射文件 resultMap 元素需要修改:

    <resultMap id="get-blob-result" class="bo.BlobTest">
      <result property="id" column="id"/>
      <result property="myblob" column="myblob"
              typeHandler="com.ibatis.sqlmap.engine.type.BlobTypeHandlerCallback"/>
    </resultMap>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值