`

Ibatis读写CLOB数据

阅读更多

Ibatis读写CLOB数据

Ibatis是一个高效,方便,易于学习的数据访问组件,在性能上比hibernate高,学习难度也比hibernate和jdo要低,而且它比直接使用jdbc方便和易于维护。所以Ibatis深入大家的喜爱,一些对性能有更高的要求的系统(如保险,金融行业系统),或改造遗留系统时,Ibatis是数据访问组件的首选。
在使用Oracle数据库时,读取CLOB和BLOB等大类型的数据一直是个比较犯难的事,一般都是通过JDBC代码来实现对CLOB和BLOB数据的读写,效果和性能都是最好的,但是代码也相当复杂,且代码难以重用。
在使用ibatis作为数据访问组件,也经常会遇到要读取CLOB,BLOB大类型数据。怎样使用Ibatis读取CLOB,BLOB数据也是一个难题,并且Oracle在这方面一直没有解决好。
公司的项目正好有这方面的需要,要求我给予解决。在网上找了很多的资料,都没有一个比较简单易用的解决办法,通过不断的验实,终于得出了比较好的解决办法,所以写成文字,大家可以分享。如果大家以后有这方面的需要就可以直接使用,少走弯路,当然如果大家有更好的办法,希望能告诉我,我当不胜感激。


准备工作:
1.        测试数据库
CREATE TABLE USERINFO(USERID VARCHAR2(5),
                         USERNAME VARCHAR2(20),
                         MEMO CLOB,
                                                constraint PK_USERINFO  primary key(USERID));
2.域模型对象
   UserInfoDTO.java
   
   


3.数据访问对象接口
        UserInfoDao.java

一、        读取CLOB,BLOB类型数据的几种方法
1.        jdbc实现
采用jdbc来读写是最原始,也是最直接的方法
UserInfoDaoImpl.java


2.        使用Spring的org.springframework.jdbc.support.lob.OracleLobHandler类处理
2.1        sql-map-config.xml的配置
<typeHandler jdbcType="CLOB" javaType="java.lang.String" callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler"/>
2.2        sqlMapClient的配置
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation"><value>/sql-map-config.xml</value></property>
  <property name="dataSource"><ref local="dataSource"/></property>
  <property name="lobHandler"><ref local="oracleLobHandler"/></property>
</bean>

<bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"
   lazy-init="true">


特别注意:采用这种方法只对数据源是直接连接Oracle 的JDBC驱动方式有效,如果你采用数据连接池作为数据源,则这种办法无效。但是一般大型的项目都是使用连接池的,所以这个方法有很大的局限性。
       
3.        通过实现Ibatis的TypeHandlerCallback接口来实现
下面是读取的方法:


sqlMap 的配置
  <resultMap id="userResult" class="com.prs.application.ehld.sample.common.dto.UserInfoDTO">
          <result property="userID" column="USERID" columnIndex="1"/>
          <result property="userName" column="USERNAME" columnIndex="2"/>
          <result property="memo"  column="memo" jdbcType="CLOB" javaType = "java.lang.String"  typeHandler =" OracleClobTypeHandlerCallback "/>
</resultMap>



二、        存在的问题
上面三种方法都存在的问题:
1.        使用jdbc来实现,就失去了使用ibatis带来的便利,同时也失去了自动事务管理的能力,还有需要自己去手工管理连接对象。代码量也相当复杂。
2.        使用spring提供的处理器,不支持采用数据连接池的数据源,有很大的局限性。
3.        通过实现ibatis的回调接口来实现,也有一定的局限性,需要新增一个类,配置也不方便,还可能会出错。

难道ibatis读写LOB大类型数据就没辙了吗?通过试验,发现可以配置ParameterMap和ResultMap就可以方便的实现对LOB的读写了,而且不用去实现任何类。只需要配置就可以了

三、        通过配置ParameterMap和ResultMap来实现对LOB类型的读写
3.1        sqlMap的配置
  <resultMap id="userResult" class="com.prs.application.ehld.sample.common.dto.UserInfoDTO">
          <result property="userID" column="USERID" columnIndex="1"/>
          <result property="userName" column="USERNAME" columnIndex="2"/>
          <result property="memo"  column="memo" jdbcType="CLOB" javaType = "java.lang.String" />
</resultMap>

  <parameterMap id="userPara" class = "com.prs.application.ehld.sample.common.dto.UserInfoDTO">
          <parameter property="userID" jdbcType="VARCHAR" javaType ="java.lang.String"/>
          <parameter property="userName" jdbcType="VARCHAR" javaType ="java.lang.String"/>
          <parameter property="memo" jdbcType="CLOB" javaType ="java.lang.String"/>
         
  </parameterMap>
3.2        插入和读取语句的配置
  <select id="getUserInfoList" resultMap="userResult" >
      SELECT
          USERINFO.USERID ,
          USERINFO.USERName ,
          USERINFO.MEMO
                FROM USERINFO
</select>


   <insert id="insertUserInfo"  parameterMap = "userPara"  >
          INSERT INTO USERINFO(USERID,
                                                   USERName,
                                                   memo)
                                  VALUES(?,?,?
                                             )
  </insert>
注意:因为使用了ParameterMap作为输入参数,在插入语句中用?号来代替属性值(如:#userId#)
                       

                        而不是常见的:
                        INSERT INTO USERINFO(USERID,
                                                   USERName,
                                                   memo)
                                  VALUES(#userId#,
                                                        #userName#,
                                                        #memo#
                                             )
但是当paramaterMap的class属性是java.util.Map类时,应该使用#userId#类似的参数,不能用?来代替。


        但是这又有一个问题,就是插入的字符串不能超过4000个字符,而CLOB类型的字段可以存4GB大小的字符。只要对userInfo对象的memo成员设置字符串超过了4000个字符,就提示“不能创建更多的套接字”,为什么会报这个错,暂是没有弄清楚。

而需求是要CLOB字段要存6000个汉字,相当于12000个英文字符。可以说是白忙了一场,没有达到目的。

四、        使用Oracle 10g的jdbc驱动程序
因为字符串只要超过了4000个字符就不能插入,所以不得不试着换一下驱动程序看看。一直以来都认为oracel的jdbc 驱动对处理LOB对象有一些问题,想看看10g出来后是不是有所改变。于是上网下载10g的驱动,一阵痛苦的等待后,问题解决,我把字符串设为12万个字符也没有问题了。

另外采用10g 的驱动就算不使用parameterMap也可以成功的插入字符串到CLOB类型字段去,请要注意的是,这样只能插入的字符一定要小于32767个。也就是说我把memo 属性设置多于32766个字符,照样插不进去。这个原因主要是jdbc驱动限制了String的长度的原因。
   <insert id="insertUserInfo"  parameterClass = "UserInfoDTO"  >
          INSERT INTO USERINFO(USERID,
                                                   USERName,
                                                   memo)
                                  VALUES(#userID#,
                                                #userName#,
                                                #memo#
                                             )
</insert>
使用10g的驱动,这样能写入32766个字符

五、        怎么读写BLOB
上面都一直在说CLOB,其实把CLOB实现了,那么BLOB也同样简单,只是注意它的java类型,如果一个字段为BLOB类型,那么在parameterMap中jdbcType 为BLOB,
把javaType设为:[]byte就可以了。
例:
  <parameterMap id="userPara" class = "com.prs.application.ehld.sample.common.dto.UserInfoDTO">
          <parameter property="userID" jdbcType="VARCHAR" javaType ="java.lang.String"/>
          <parameter property="userName" jdbcType="VARCHAR" javaType ="java.lang.String"/>
          <parameter property="memo" jdbcType="BLOB" javaType ="[]byte"/>
         
  </parameterMap>

假设memo在数据库中为BLOB 类型

那么在javaBean中memo的java类型为[]byte


六、        总结
采用10g的驱动,和通过配置parameterMap和resultMap能够轻松和完美的解决LOB大型数据的读写,无需要编写新的java来实现,也没有局限性。

分享到:
评论

相关推荐

    ibatis oracle clob

    1. **插入CLOB数据**:在iBATIS的映射文件中,需要使用`&lt;clob&gt;`标签来处理CLOB字段。例如,当向数据库插入CLOB字段时,可以这样编写XML映射: ```xml INSERT INTO table_name (column_name) VALUES (#{value}) ...

    iBATIS操作Oracle CLOB数据

    本文将深入探讨如何在iBATIS中有效地处理Oracle的CLOB数据。 首先,我们需要了解什么是CLOB。CLOB是一种用于存储大量字符数据的数据类型,它可以容纳最大4GB的单个文本对象。在Oracle中,CLOB通常用于存储大段的...

    ibatis 读取oracle clob类型

    ibatis 读取oracle clob类型

    Spring+Struts+ibatis下配置数据读写分离及事务(一)

    本文将深入探讨如何在Spring、Struts和iBATIS这三大流行框架的集成环境中实现数据读写分离以及事务控制。我们将不涉及具体的代码实现,而是侧重于理论背景和设计原则。 首先,让我们理解数据读写分离的概念。数据...

    Ibatis .net框架多数据源配置

    Ibatis .net框架多数据源配置是针对在同一个应用程序中需要连接并操作多个数据库场景的一种解决方案。Ibatis是一个流行的持久层框架,它允许开发者将SQL语句与Java或.NET代码解耦,提供了一种灵活的方式来处理数据库...

    mybatis 对clob类型转换

    在实际操作中,可能会遇到如“数据过长”或“内存不足”等异常,这可能是因为CLOB数据超过了数据库或JVM的限制。为避免这些问题,可以考虑分段读写CLOB,或者调整数据库参数。另外,确保在MyBatis的...

    ibatis_数据缓存

    iBatis 数据缓存机制是提高数据库访问性能的重要手段,它允许将查询结果存储在内存中,以便后续相同查询能够快速获取数据,而无需每次都执行SQL查询。在深入理解iBatis的Cache概念之前,首先需要知道iBatis是一个轻...

    ibatis实现数据的操作

    本篇文章将详细讲解如何利用Ibatis实现数据的连接、增加、查询、删除和修改(CRUD)操作,以及.xml文件在SQL映射中的作用。 首先,Ibatis是一个轻量级的Java ORM(对象关系映射)框架,它的核心理念是将SQL语句与...

    ibatis 连接字符串 SqlMapConfig.xml

    这个文件是iBATIS的核心配置文件,它包含了数据源、事务管理器、SQL映射文件等信息,确保了应用程序能够正确地连接到数据库并执行SQL语句。 在SqlMapConfig.xml中,最重要的部分是数据库连接的配置,通常包括以下几...

    ibatis资料ibatis资料

    标题和描述中反复提及的是“ibatis资料”,这表明主题是关于iBATIS,一个已退役的开源Java数据访问框架。iBATIS最初由James Gullickson创建,它允许开发者将SQL语句直接嵌入到Java代码中,提供了数据库操作的便利性...

    ibatis总结 ibatis ibatis ibatis ibatis

    Ibatis的配置文件`sqlmapConfig.xml`包含了数据源、事务管理器、SqlSessionFactory等核心设置。在Java代码中,可以使用如下的方式加载配置文件: ```java String resource = ...

    ibatis demo,ibatis例子,ibatis示例

    Ibatis的出现,解决了传统JDBC中手动编写SQL和结果集映射的繁琐工作,提供了更加灵活的数据访问接口。 在"ibatis demo"中,我们通常会看到以下核心概念和知识点: 1. **配置文件**:Ibatis的配置文件(mybatis-...

    ibatis 数据缓存.pdf

    ibatis 数据缓存,讨论了ibatis 数据缓存方面的概念,即用法,用到ibatis 数据缓存的可以参考一下

    ibatis自定义数据类型在不支持中文的数据库存储汉字

    `iBatis`,作为一个轻量级的持久层框架,提供了自定义数据类型的功能,帮助我们在这些数据库中存储汉字。 `iBatis`是Java领域中广泛使用的SQL映射框架,它允许开发者将SQL语句直接写在配置文件中,与Java代码解耦,...

    Ibatis和Spring整合例子,实现增删改查功能

    Ibatis和Spring整合例子,实现增删改查功能.

    在SCAModule中使用iBATIS框架实现数据持久层

    火龙果软件工程技术中心 本文内容包括:先决条件导入示例项目引入iBATIS实现StockService组件总结下载参考资料在完成SCAModule建模后用Java对象进行实现时,采用Hibernate和采用iBATIS实现SCAModule的数据持久层,...

    ibatis源码,ibatis源码 ibatis源码 ibatis源码

    iBatis的配置文件SqlMapConfig.xml是系统启动时加载的关键,它包含了数据源(DataSource)、事务管理器(TransactionManager)和SqlMap配置信息。解析这个XML文件的过程涉及到DOM或SAX解析器,源码中这部分功能通常...

    ibatis乱码解决方法(ibatis独立)

    - 如果是从文件中读取或写入数据,确保文件的读写操作使用了与数据库相同的编码格式。 8. **字符集转换**: - 使用Java的`Charset`类进行编码转换,如`new String(byte[], "GBK")`用于GBK编码的字符串转换。 ...

    装饰模式 切换 ibatis 多数据源

    在IT领域,尤其是在数据库访问层,装饰模式经常被用于切换不同数据源,如题目所提的"切换iBatis多数据源"。 iBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。在多数据源场景下,可能需要...

Global site tag (gtag.js) - Google Analytics