科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Spring让LOB数据操作变得简单易行

Spring让LOB数据操作变得简单易行

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文讲解了在 Spring 中处理 LOB 数据的原理和方法

作者:陈雄华 来源:Impress Watch中文站 2007年10月13日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共5页)

在 Hibernate 中操作 LOB 数据

提示

使用 Spring JDBC 时,我们除了可以按 byte[]、String 类型处理 LOB 数据外,还可以使用流的方式操作 LOB 数据,当 LOB 数据体积较大时,流操作是唯一可行的方式。可惜,Spring 并未提供以流方式操作 LOB 数据的 UserType(记得 Spring 开发组成员认为在实现上存在难度)。不过,www.atlassian.com 替 Spring 完成了这件难事,读者可以通过 这里 了解到这个满足要求的 BlobInputStream 类型。

  Hibernate 为处理特殊数据类型字段定义了一个接口:org.hibernate.usertype.UserType。Spring 在 org.springframework.orm.hibernate3.support 包中为 BLOB 和 CLOB 类型提供了几个 UserType 的实现类。因此,我们可以在 Hibernate 的映射文件中直接使用这两个实现类轻松处理 LOB 类型的数据。
  • BlobByteArrayType:将 BLOB 数据映射为 byte[] 类型的属性;
  • BlobStringType:将 BLOB 数据映射为 String 类型的属性;
  • BlobSerializableType:将 BLOB 数据映射为 Serializable 类型的属性;
  • ClobStringType:将 CLOB 数据映射为 String 类型的属性;

  下面我们使用 Spring 的 UserType 为 Post 配置 Hibernate 的映射文件,如 清单 10 所示:

  清单 10 . LOB 数据映射配置

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping auto-import="true" default-lazy="false"> 
  <class name="com.baobaotao.domain.Post" table="t_post"> 
    <id name="postId" column="post_id"> 
      <generator class="identity" /> 
    </id> 
    <property name="userId" column="user_id"/> 
    <property name="postText" column="post_text"   
    type="org.springframework.orm.hibernate3.support.ClobStringType"/>①对应 CLOB 字段 
    <property name="postAttach" column="post_attach"  
     type="org.springframework.orm.hibernate3.support.BlobByteArrayType"/>② BLOB 字段 
    <property name="postTime" column="post_time" type="date" /> 
    <many-to-one name="topic" column="topic_id" class="com.baobaotao.domain.Topic" /> 
  </class> 
</hibernate-mapping> 

  postText 为 String 类型的属性,对应数据库的 CLOB 类型,而 postAttach 为 byte[] 类型的属性,对应数据库的 BLOB 类型。分别使用 Spring 所提供的相应 UserType 实现类进行配置,如 ① 和 ② 处所示。

  在配置好映射文件后,还需要在 Spring 配置文件中定义 LOB 数据处理器,让 SessionFactory 拥有处理 LOB 数据的能力:

  清单 11 . 将 LobHandler 注入到 SessionFactory 中

… 
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" 
 lazy-init="true" /> 
<bean id="sessionFactory"   
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
  <property name="dataSource" ref="dataSource" /> 
  <property name="lobHandler" ref="lobHandler" /> ① 设置 LOB 处理器 
  … 
</bean> 

  在一般的数据库(如 DB2)中,仅需要简单地使用 HibernateTemplate#save(Object entity) 等方法就可以正确的保存 LOB 数据了。如果是 Oracle 9i 数据库,还需要配置一个本地 JDBC 抽取器,并使用特定的 LobHandler 实现类,如 清单 4 所示。

  使用 LobHandler 操作 LOB 数据时,需要在事务环境下才能工作,所以必须事先配置事务管理器,否则会抛出异常。

  在 iBatis 中操作 LOB 数据

  iBatis 为处理不同类型的数据定义了一个统一的接口:com.ibatis.sqlmap.engine.type.TypeHandler。这个接口类似于 Hibernate 的 UserType。iBatis 本身拥有该接口的众多实现类,如 LongTypeHandler、DateTypeHandler 等,但没有为 LOB 类型提供对应的实现类。Spring 在 org.springframework.orm.ibatis.support 包中为我们提供了几个处理 LOB 类型的 TypeHandler 实现类:
  • BlobByteArrayTypeHandler:将 BLOB 数据映射为 byte[] 类型;
  • BlobSerializableTypeHandler:将 BLOB 数据映射为 Serializable 类型的对象;
  • ClobStringTypeHandler:将 CLOB 数据映射为 String 类型;

  当结果集中包括 LOB 数据时,需要在结果集映射配置项中指定对应的 Handler 类,下面我们采用 Spring 所提供的实现类对 Post 结果集的映射进行配置。

  清单 12 . 对 LOB 数据进行映射

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" 
    "http://ibatis.apache.org/dtd/sql-map-2.dtd"> 
<sqlMap namespace="Post"> 
  <typeAlias alias="post" type="com.baobaotao.domain.Post"/> 
   <resultMap id="result" class="post">    
        <result property="postId" column="post_id"/>    
        <result property="userId" column="user_id"/>    
        <result property="postText" column="post_text" ① 读取 CLOB 类型数据 
        typeHandler="org.springframework.orm.ibatis.support.ClobStringTypeHandler"/> 
        <result property="postAttach" column="post_attach" ② 读取 BLOB 类型数据 
        typeHandler="org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler"/> 
    </resultMap>  
  <select id="getPost" resultMap="result"> 
    SELECT post_id,user_id,post_text,post_attach,post_time  
    FROM t_post  WHERE post_id =#postId# 
  </select> 
  <insert id="addPost"> 
    INSERT INTO t_post(user_id,post_text,post_attach,post_time)  
    VALUES(#userId#, 
  #postText,handler=org.springframework.orm.ibatis.support.ClobStringTypeHandler#, ③ 
  #postAttach,handler=org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler#, ④ 
  #postTime#) 
  </insert> 
</sqlMap>  

提示

为每一个 LOB 类型字段分别指定处理器并不是一个好主意,iBatis 允许在 sql-map-config.xml 配置文件中通过 <typeHandler> 标签统一定义特殊类型数据的处理器,如:
<typeHandler jdbcType="CLOB" javaType="java.lang.String" callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler"/>

  当 iBatis 引擎从结果集中读取或更改 LOB 类型数据时,都需要指定处理器。我们在 ① 和 ② 处为读取 LOB 类型的数据指定处理器,相似的,在 ③ 和 ④ 处为插入 LOB 类型的数据也指定处理器。

  此外,我们还必须为 SqlClientMap 提供一个 LobHandler:

  清单 13. 将 LobHandler 注入到 SqlClientMap 中

<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"     
 lazy-init="true" /> 
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> 
 <property name="dataSource" ref="dataSource" /> 
 <property name="lobHandler" ref="lobHandler" /> ①设置LobHandler 
 <property name="configLocation" 
  value="classpath:com/baobaotao/dao/ibatis/sql-map-config.xml" /> 
</bean> 

  处理 LOB 数据时,Spring 要求在事务环境下工作,所以还必须配置一个事务管理器。iBatis 的事务管理器和 Spring JDBC 事务管理器相同,此处不再赘述。

  小结

  本文就 Spring 中如何操作 LOB 数据进行较为全面的讲解,您仅需简单地配置 LobHandler 就可以直接在程序中象一般数据一样操作 LOB 数据了。对于 ORM 框架来说,Spring 为它们分别提供了支持类,您仅要使用相应的支持类进行配置就可以了。因此您会发现在传统 JDBC 程序操作 LOB 头疼的问题将变得轻松了许多。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章