- 浏览: 488521 次
- 性别:
- 来自: 武汉
-
最新评论
-
zyzyzy123:
请问有工程吗,我现在正在实现打电话的功能,但是一直不通,怀疑是 ...
实用的java 串口通信程序 -
wuhaitong:
引用[img][/img][*][url][/url] ...
jbpm -
迷糊_le:
maven命令, 蛮好的,谢谢
maven eclipse -
Wuaner:
不错的文章 , 谢谢分享!
Hadoop -
yuqihengsheng:
strong 很细
HighLighter
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
- import java.io.Serializable;
- public class UserInfoDTO implements Serializable {
- /*用户id*/
- private String userID;
- /*用户名*/
- private String userName;
- /*备注*/
- private String memo;
- public String getMemo() {
- return memo;
- }
- public void setMemo(String memo) {
- this.memo = memo;
- }
- public String getUserID() {
- return userID;
- }
- public void setUserID(String userID) {
- this.userID = userID;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- }
3.数据访问对象接口
UserInfoDao.java
- public interface UserInfoDao {
- public List getUsers(UserInfoDTO user) throws DataAccessException;
- public void insertUser(UserInfoDTO user) throws DataAccessException;
- }
一、 读取CLOB,BLOB类型数据的几种方法
1. jdbc实现
采用jdbc来读写是最原始,也是最直接的方法
UserInfoDaoImpl.java
- public class UserInfoDaoImpl extends SqlMapClientDaoSupport implements
- UserInfoDao {
- Connection con = null;
- private Connection getConnection() throws SQLException {
- Connection con = null;
- con = this.getSqlMapClientTemplate().getDataSource().getConnection();
- con.setAutoCommit(false);
- return con;
- }
- public void insertUser(UserInfoDTO user) throws DataAccessException {
- try {
- this.con = this.getConnection();
- final String insertSql = "INSERT INTO USERINFO(USERID,USERName,memo) VALUES(?,?,?)";
- final String selectSql = "SELECT MEMO FROM USERINFO WHERE USERID = ? FOR UPDATE";
- final String updateSql = "UPDATE USERINFO SET MEME = ? WHERE USERID = ?";
- PreparedStatement ps = con.prepareStatement(insertSql);
- ps.setString(1, user.getUserID());
- ps.setString(2, user.getUserName());
- ps.setClob(3, CLOB.empty_lob());
- ps.executeUpdate();
- ps.close();
- ps = this.con.prepareStatement(selectSql);
- ps.setString(1, user.getUserID());
- ResultSet rs = ps.executeQuery();
- rs.next();
- CLOB memo = (CLOB) rs.getClob(1);
- memo.setString(1, user.getMemo());
- ps = this.con.prepareStatement(updateSql);
- ps.setClob(1, memo);
- ps.setString(2, user.getUserID());
- ps.executeUpdate();
- ps.close();
- this.con.commit();
- } catch (Exception ex) {
- throw new DataAccessResourceFailureException(ex.getMessage(), ex);
- } finally {
- try {
- if (this.con != null)
- this.con.close();
- } catch (Exception ex) {
- throw new DataAccessResourceFailureException(ex.getMessage(),
- ex);
- }
- }
- }
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接口来实现
下面是读取的方法:
- public class OracleClobTypeHandlerCallback implements TypeHandlerCallback {
- public void setParameter(ParameterSetter setter, Object obj)
- throws SQLException {
- // TODO Auto-generated method stub
- CLOB clob = CLOB.empty_lob();
- clob.setString(1, (String)obj);
- setter.setClob(clob);
- }
- public Object getResult(ResultGetter getter) throws SQLException {
- CLOB clob = (CLOB) getter.getClob();
- return (clob == null || clob.length() == 0 )? null :clob.getSubString((long)1, (int)clob.length());
- }
- public Object valueOf(String param) {
- // TODO Auto-generated method stub
- return null;
- }
- }
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"/>
- <span style="color:darkred;"><result property="memo" column="memo" jdbcType="CLOB" javaType = "java.lang.String" /></span></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"/>
- <span style="color:darkred;"><parameter property="memo" jdbcType="CLOB" javaType ="java.lang.String"/></span>
- </parameterMap>
- <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(<span style="color:darkred;">?,?,?</span>
- )
- </insert>
而不是常见的:
- 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>
五、 怎么读写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"/>
- <span style="color:red;"><parameter property="memo" jdbcType="BLOB" javaType ="[]byte"/></span>
- </parameterMap>
假设memo在数据库中为BLOB 类型
那么在javaBean中memo的java类型为[]byte
六、 总结
采用10g的驱动,和通过配置parameterMap和resultMap能够轻松和完美的解决LOB大型数据的读写,无需要编写新的java来实现,也没有局限性。
发表评论
-
安装和使用memcached
2014-04-16 16:24 649如何将 memcached 融入到 ... -
applicationContext.xml
2013-08-09 09:05 952<?xml version="1.0&quo ... -
注释驱动的 Spring cache 缓存介绍
2013-08-08 07:04 670概述 Spring 3.1 引入了激动人心的基于注释(an ... -
Spring2.5 Annotations
2013-08-08 06:33 869完成setXxxx功能,即配置文件的 <propert ... -
Spring基于注解的缓存配置--EHCache AND OSCache
2013-08-07 23:21 1042本文将构建一个普通工程来说明spring注解缓存的使用方式, ... -
Ehcache 整合Spring 使用页面、对象缓存
2013-08-07 22:51 906Ehcache 整合Spring 使用页面、对象缓存 ... -
javassist教程和示例
2013-05-18 08:57 2023Javassist是一个执行字节 ... -
ZooKeeper官方文档
2013-05-16 17:09 1568介绍(源自ZooKeeper官方文档) 学习HBase过程 ... -
ZooKeeper -例子
2013-05-16 17:08 1232ZooKeeper ZooKeepe ... -
Spring整合Hessian访问远程服务
2013-05-15 13:44 867Spring整合Hessian访问远程服务 目录 1.1 ... -
redis
2013-05-14 11:44 778redis是一个key-value存储系统。和Memcach ... -
spring 资源访问
2013-05-13 08:26 1017spring在java基础上封装了资源访问,简单易用。 R ... -
ZooKeeper——入门
2013-05-08 16:12 918ZooKeeper——入门 博客分类: ZooK ... -
分布式服务框架 Zookeeper -- 管理分布式环境中的数据(IBM)
2013-05-08 14:07 793安装和配置详解 本文 ... -
分布式协调服务---Zookeeper
2013-05-08 14:05 7851、Zookeeper overview Zookee ... -
Hibernate
2013-03-28 13:04 937一、简述 Hibernate 和 JD ... -
Apache+Tomcat集群配置详解
2013-02-01 10:52 907Apache + Tomcat集群配置详解(1) 一、 ... -
Apache+Jboss集群基于反向代理的负载均衡
2013-02-01 10:40 2510假设三台机器IP分别为172.29.128.100、172. ... -
spring + ibatis 多数据源事务(分布式事务)管理配置方法
2012-12-17 15:18 1284spring + ibatis 多数据源事务(分布式事务 ... -
Hessian序列化不设SerializerFactory性能问题
2012-10-31 09:47 1521Hessian序列化不设SerializerFactor ...
相关推荐
综上所述,通过iBATIS操作Oracle的CLOB数据,需要对iBATIS的映射文件、类型处理器以及Oracle的CLOB特性有深入理解。在实际开发中,合理配置和使用这些机制,能够有效地管理大量文本数据,同时保持代码的简洁性和可...
标题 "ibatis oracle clob" 涉及到的是在Java开发中,使用iBATIS框架与Oracle数据库交互时处理CLOB(Character Large Object)类型数据的问题。CLOB是Oracle数据库用于存储大文本数据(如XML文档、长篇文章等)的...
ibatis 读取oracle clob类型
创建一个实现`org.apache.ibatis.type.TypeHandler`接口的类,重写`setParameter`和`getResult`方法,确保在SQL语句执行前能将Java对象转换为CLOB,执行后又能从CLOB还原为原始数据。 2. **配置MyBatis** 在...
1. **数据类型**:Oracle支持多种数据类型,如`NUMBER`(数值)、`VARCHAR2`(可变长度字符串)、`DATE`(日期时间)、`CLOB`(大对象)等。 2. **索引**:为了提高查询效率,Oracle允许为表的列创建索引。B树索引...
Oracle支持复杂的数据类型,如BLOB和CLOB,适合存储大量非结构化数据。Oracle的分区功能也是其处理大数据的关键特性,通过将大表分成小块,可以实现快速的数据检索和管理。此外,Oracle的PL/SQL语言提供了过程编程...
springmvc ibatis 整合, 解决BLOB,CLOB等大字段的问题,内置查询缓存 和解决SpringMVC 返回JSON下载,乱码等问题 内部并没有实际的项目,只是一个搭建好的环境,方便较少大家时间, 并提供了一个DEMO ,紧为不了解...
接着,配置了两个自定义的`typeHandler`,分别对应于Java中的`object`和`string`类型,这里使用了iBATIS提供的`BlobTypeHandlerCallback`和`ClobTypeHandlerCallback`来处理BLOB和CLOB类型的数据库字段。 然后,...
在MySQL数据库中,大对象通常存储在BLOB(Binary Large Object)或CLOB(Character Large Object)类型字段中。对于图片这类二进制数据,我们会选择BLOB类型。以下是一些关键知识点: 1. **配置iBatis**:在iBatis...
例如,`result`用于快速获取基本数据,而扩展的`resultMap`则包含更详细或大型的数据字段,如CLOB/BLOB类型,这样可以按需加载数据,避免不必要的资源消耗。 - **POJO与DTO并用**:虽然文中提到“通常都没有专门...
1. **LOB字段处理**:SSH提供了处理大对象(LOB)字段的方法,如BLOB和CLOB,确保大数据类型的存储和检索。 2. **文件上传**:SSH框架支持文件上传,通常通过Struts2的上传组件实现,需要注意文件大小限制和安全性...
<typeHandler jdbcType="CLOB" javaType="java.lang.String" callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler"/> ``` 这里的配置指定了BLOB类型对应的Java类型为`byte[]`,并通过`...
Oracle提供多种数据类型,如CHAR、VARCHAR2、NUMBER、DATE以及LOB(包括BLOB和CLOB)。日期格式可以使用TO_DATE函数转换,例如`to_date('2016-6-1','yyyy-MM-dd')`,或者直接使用DATE'2016-6-1'。 分析函数如RANK()...
在dbking中,所有的数据库数据只有五种数据类型,String、Number(BigDecimal)、Timestamp、Clob(String)、Blob(byte[]),经过反复测试后,我们会例出各种数据库数据类型到这五种类型的映射表,当然我们也有...
开发框架如SSH(Struts+Spring+Hibernate)和SSI(SpringMVC+Spring+IBatis)经常与Oracle配合使用。 配置监听器是Oracle数据库管理的重要环节,监听器文件(如Oracle.Listener和OracleService)负责处理客户端连接...
处理BLOB 和 CLOB对象 11.7.3. 在IN语句中传入一组参数值 11.7.4. 处理复杂类型的存储过程调用 12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring容器中创建 ...
处理BLOB 和 CLOB对象 11.7.3. 在IN语句中传入一组参数值 11.7.4. 处理复杂类型的存储过程调用 12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring容器中创建 ...