Hibernate、iBATIS 与 BLOB [转]

本文介绍了使用Hibernate和iBATIS SQLMaps处理不同数据库(包括SQL Server、MySQL和Oracle)中的BLOB数据的方法,涵盖了数据的存储与检索过程。
2007-04-16   版权声明
我知道这篇文章阅读量很大,但是请要继续转载本文的同志注意一下,本文是我在 2005 年春节期间写的,春节是合家团圆的日子,所以在这个时候写点东西不容易,整整花了我将近 20 天的时间啊。请保留原文版权信息 OK?
----------------------------------------------------------------------------------------------------
在存储图片、可执行文件等二进制信息时(当然直接放在文件系统上也行), 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>



请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处: http://www.blogjava.net/rosen

 
跟网型逆变器小干扰稳定性分析控制策略优化研究(Simulink仿真实现)内容概要:本文围绕跟网型逆变器的小干扰稳定性展开分析,重点研究其在电力系统中的动态响应特性及控制策略优化问题。通过构建基于Simulink的仿真模型,对逆变器在不同工况下的小信号稳定性进行建模分析,识别系统可能存在的振荡风险,并提出相应的控制优化方法以提升系统稳定性和动态性能。研究内容涵盖数学建模、稳定性判据分析、控制器设计参数优化,并结合仿真验证所提策略的有效性,为新能源并网系统的稳定运行提供理论支持和技术参考。; 适合人群:具备电力电子、自动控制或电力系统相关背景,熟悉Matlab/Simulink仿真工具,从事新能源并网、微电网或电力系统稳定性研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 分析跟网型逆变器在弱电网条件下的小干扰稳定性问题;② 设计并优化逆变器外环内环控制器以提升系统阻尼特性;③ 利用Simulink搭建仿真模型验证理论分析控制策略的有效性;④ 支持科研论文撰写、课题研究或工程项目中的稳定性评估改进。; 阅读建议:建议读者结合文中提供的Simulink仿真模型,深入理解状态空间建模、特征值分析及控制器设计过程,重点关注控制参数变化对系统极点分布的影响,并通过动手仿真加深对小干扰稳定性机理的认识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值