随笔-72  评论-63  文章-0  trackbacks-0

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 的出现使一切都简单了,写入、 取出 程序和上面的 SQL Server 一样。

http://java.ccidnet.com/art/297/20051117/374459_1.html

posted on 2006-06-18 15:07 船长 阅读(1171) 评论(0)  编辑  收藏 所属分类: J2EE

只有注册用户登录后才能发表评论。


网站导航: