`

iBatis整理——Spring环境下批处理实现

阅读更多
最近做一个小项目,用到Spring+iBatis。突然遇到一个很久远,却很实在的问题:在Spring下怎么使用iBatis的批处理实现?

大概是太久没有写Dao了,这部分真的忘得太干净了。

从4个层面分析这部分实现:
  1. iBatis的基本实现
  2. 基于事务的iBatis的基本实现
  3. 基于事务的Spring+iBatis实现
  4. 基于回调方式的Spring+iBatis实现


1.iBatis的基本实现
iBatis通过SqlMapClient提供了一组方法用于批处理实现:
  1. startBatch() 开始批处理
  2. executeBatch() 执行批处理

代码如下:
	public void create(List<Reply> replyList) {

		try {
			// 开始批处理
			sqlMapClient.startBatch();

			for (Reply reply: replyList) {
				// 插入操作
				sqlMapClient.insert("Reply.create", reply);
			}
			// 执行批处理
			sqlMapClient.executeBatch();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

这是基于iBatis的最基本实现,如果你一步一步debug,你会发现:其实,数据库已经执行了插入操作!
因此,除了这两个核心方法外,你还需要开启事务支持。否则,上述代码只不过是个空架子!

2.基于事务的iBatis的基本实现
事务处理:
  1. startTransaction() 开始事务
  2. commitTransaction() 提交事务
  3. endTransaction() 结束事务


我们以insert操作为例,把它们结合到一起:
	public void create(List<Reply> replyList) {

		try {
			// 开始事务
			sqlMapClient.startTransaction();
			// 开始批处理
			sqlMapClient.startBatch();

			for (Reply reply: replyList) {
				// 插入操作
				sqlMapClient.insert("Reply.create", reply);
			}
			// 执行批处理
			sqlMapClient.executeBatch();

			// 提交事务
			sqlMapClient.commitTransaction();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {  
 			 try {
				// 结束事务
				sqlMapClient.endTransaction();
        		    } catch (SQLException e) {
       			         e.printStackTrace();
       			     }
		}  
	}

replyList是一个List,要把这个List插入到数据库,就需要经过这三个步骤:
  1. 开始批处理 startBatch()
  2. 插入      insert()
  3. 执行批处理 executeBatch()

如果要在Spring+iBatis中进行批处理实现,需要注意使用同一个sqlMapClient!同时,将提交事务的工作交给Spring统一处理!

3.基于事务的Spring+iBatis实现
	public void create(List<Reply> replyList) {
		if (!CollectionUtils.isEmpty(replyList)) {
			// 注意使用同一个SqlMapClient会话
			SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient();

			try {
				// 开始事务
				sqlMapClient.startTransaction();
				// 开始批处理
				sqlMapClient.startBatch();
				for (Reply reply : replyList) {
					// 插入操作
					sqlMapClient.insert("Reply.create", reply);
				}

				// 执行批处理
				sqlMapClient.executeBatch();
				// 提交事务 交给Spring统一控制
				// sqlMapClient.commitTransaction();

			} catch (Exception e) {
				e.printStackTrace();
			} finally {  
 				 try {
					// 结束事务
					sqlMapClient.endTransaction();
        			    } catch (SQLException e) {
       				         e.printStackTrace();
       				     }
			}  
		}
	}

注意使用同一个sqlMapClient:
SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient();
如果直接sqlMapClientTemplate执行insert()方法,将会造成异常!

想想,还有什么问题?其实问题很明显,虽然解决了批处理实现的问题,却造成了事务代码入侵的新问题。 这么做,有点恶心!
除此之外,异常的处理也很恶心,不能够简单的包装为 DataAccessException 就无法被Spring当作统一的数据库操作异常做处理。


4.基于回调方式的Spring+iBatis实现
如果观察过Spring的源代码,你一定知道,Spring为了保持事务统一控制,在实现ORM框架时通常都采用了回调模式,从而避免了事务代码入侵的可能!
修改后的代码如下:
	@SuppressWarnings("unchecked")
	public void create(final List<Reply> replyList) {
		// 执行回调
		sqlMapClientTemplate.execute(new SqlMapClientCallback() {
			// 实现回调接口
			public Object doInSqlMapClient(SqlMapExecutor executor)
					throws SQLException {
				// 开始批处理
				executor.startBatch();
				for (Reply reply : replyList) {
					// 插入操作
					executor.insert("Reply.create", reply);

				}
				// 执行批处理
				executor.executeBatch();

				return null;

			}
		});

	}

注意,待遍历的参数replyList需要加入final标识!即,待遍历对象不能修改!
引用
public void create(final List<Reply> replyList)

这样做,就将事务处理的控制权完全交给了Spring!
简述:
  1. SqlMapClientCallback 回调接口
  2. doInSqlMapClient(SqlMapExecutor executor) 回调实现方法
  3. DataAccessException 最终可能抛出的异常

通过上述修改,最终能够解决第三种实现方式中的种种不足!

Spring对iBatis提供的支持还是不够完善,即便是现在最新的Spring3.0.4。最开始,本打算用Spring3.0+iBatis3.0,结果Spring报错,说找不到“com.ibatis.xxxxx”完全是iBatis2.x的包路径!汗颜~ 还是Hibernate比较得宠!

做个小记录,呵呵!
19
2
分享到:
评论
13 楼 bluend1004 2013-09-06  
您好 求解释,博文中提到的”却造成了事务代码入侵的新问题“能具体解释下吗?谢谢
12 楼 veenter 2013-07-17  
snowolf 写道
sunjichao 写道
Copperfield 写道
哥们,咨询个问题:
第四种我试了一下, 在执行executor.executeBatch();时,一旦遇到异常,数据没有批量回滚,10条数据有2条异常,则正常插入8条数据,这个很是不解。。。

遇到同样的问题,求解释。

有没有配置事务层?这段代码很久了,我都是在service用配置事务。如果没有事务控制,不会回滚!


贴一下代码,看看是如果操作的
11 楼 snowolf 2012-06-25  
sunjichao 写道
Copperfield 写道
哥们,咨询个问题:
第四种我试了一下, 在执行executor.executeBatch();时,一旦遇到异常,数据没有批量回滚,10条数据有2条异常,则正常插入8条数据,这个很是不解。。。

遇到同样的问题,求解释。

有没有配置事务层?这段代码很久了,我都是在service用配置事务。如果没有事务控制,不会回滚!
10 楼 sunjichao 2011-12-20  
Copperfield 写道
哥们,咨询个问题:
第四种我试了一下, 在执行executor.executeBatch();时,一旦遇到异常,数据没有批量回滚,10条数据有2条异常,则正常插入8条数据,这个很是不解。。。

遇到同样的问题,求解释。
9 楼 77tt77 2011-04-15  
学习了。
8 楼 Copperfield 2011-02-23  
哥们,咨询个问题:
第四种我试了一下, 在执行executor.executeBatch();时,一旦遇到异常,数据没有批量回滚,10条数据有2条异常,则正常插入8条数据,这个很是不解。。。
7 楼 snowolf 2010-12-29  
guozq518 写道
我就是有的第三种来处理的  第四种方法没太看明白。

代码入侵的问题,如果用回调方式,你不需要考虑捕获异常。
6 楼 guozq518 2010-12-29  
我就是有的第三种来处理的  第四种方法没太看明白。
5 楼 snowolf 2010-10-21  
远去的渡口 写道
LZ是指第三种方式时直接使用SqlMapClientTemplate报错么?不好意思理解有误,第三种还没有试过,有时间也试一下

主要不是异常问题的考虑,主要是考虑事务统一处理!
4 楼 远去的渡口 2010-10-21  
LZ是指第三种方式时直接使用SqlMapClientTemplate报错么?不好意思理解有误,第三种还没有试过,有时间也试一下
3 楼 远去的渡口 2010-10-21  
其实我还没有完全搞明白 ,不过采用你这种方法试了,效率还不错的,实现了批处理。
另外,如果直接sqlMapClientTemplate执行insert()方法,将会造成异常!
我是直接用this.getSqlMapClientTemplate().execute(new SqlMapClientCallback() {没有抛出异常。
2 楼 snowolf 2010-09-07  
lyy3323 写道
。。。。。。。SPRING,自动拦截事务就可以了。无需回调这么麻烦。

真正的事务处理仍然在spring中的aop控制之中,当然是通过声明式事务自动拦截!
你可能没明白我的意思,或者说我没听明白你的涵义!
起初,我也只是调用批处理,心想只要我做了声明式事务,就能够做到事务控制,但却发现:不加事务代码,SqlMapClient 不会执行批处理,反而是简单的单条数据插入!所以,开始加事务代码,发现很繁琐,又要手动控制事务,又要破获异常,仔细看Spring源码,才恍然大悟——spring中所有的ORM实现都是用了回调方式,目的就是要兼容事务控制,包括我所需要的批处理!

PS:如果你有更好的办法,麻烦给点提示,我再测试测试!
1 楼 lyy3323 2010-09-07  
。。。。。。。SPRING,自动拦截事务就可以了。无需回调这么麻烦。

相关推荐

    ibatis 完美例子 一对多 批处理 事务 和 spring struts2集成

    本文将深入探讨如何利用Ibatis实现一对多关系、批处理、事务管理和与Spring及Struts2的集成。 首先,让我们来看一下“一对多”关系。在数据库设计中,一对多关系很常见,比如一个用户可以有多个订单。在Ibatis中,...

    ibatis的两种方式实现批处理.doc

    在Spring模式下,iBatis提供了SqlMapClient来实现批处理操作。SqlMapClient是一个线程安全的客户端对象,用于执行SQL语句。在批处理操作中,需要使用SqlMapClient的startTransaction()方法来启动事务,startBatch()...

    ibatis批处理.doc

    例如,下面的代码展示了如何在Spring模式下使用iBATIS进行批处理: ```java public void batchAddExamlog(List&lt;Examlog&gt; examlogList) throws SQLException { SqlMapClient smc = this.getSqlMapClient(); try ...

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

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

    Spring高版本对ibatis的支持

    最近想在最新的Spring5.0中集成ibatis(不是mybatis),发现已经不在支持SqlmapClientTemplate和SqlmapClientFactoryBean,于是搞了这个工具jar来进行支持如下配置 &lt;bean id="sqlMapClient" class="org.spring...

    ibatis 2 and spring 例子

    标题 "ibatis 2 and spring 例子" 指向的是一个关于如何集成并使用iBatis 2框架与Spring框架的示例教程。iBatis是一个轻量级的持久层框架,它允许开发者将SQL语句直接写在配置文件中,避免了ORM(对象关系映射)框架...

    Spring与iBATIS的集成

    Spring与iBATIS的集成 iBATIS似乎已远离众说纷纭的OR框架之列,通常人们对非常流行的Hibernate情有独钟。但正如Spring A Developer's Notebook作者Bruce Tate 和Justin Gehtland所说的那样,与其他的OR框架相比...

    Struts2+Spring+iBATIS架构实现

    Struts2 Spring iBATIS 架构 实现 Struts2 Spring iBATIS 架构 实现 Struts2 Spring iBATIS 架构 实现 Struts2 Spring iBATIS 架构 实现

    ibatis2+spring

    在Spring中,我们可以创建一个接口,然后通过Spring的ProxyFactoryBean来创建代理对象,实现代理对象对iBatis的SqlSession方法调用。例如,定义一个ProductDao接口: ```java public interface ProductDao { List...

    ibatis与spring整合

    ### ibatis与Spring框架整合详解 #### 一、ibatis简介 ibatis是一个开源的、基于Java的持久层框架,它提供了SQL映射的方式来进行数据库访问。与Hibernate等其他ORM框架相比,ibatis更加轻量级,对于那些只需要简单...

    maven搭建SpringMVC+spring+ibatis

    Ibatis与Spring框架集成后,可以使用Spring的DI功能管理数据库连接,同时通过MyBatis-Spring提供的MapperScannerConfigurer自动扫描并注册Mapper接口,实现DAO层的便捷开发。 在SpringMVC+Spring+Ibatis的架构中,...

    iBatis和Spring整合

    iBatis和Spring整合 iBatis和Spring整合

    spring与ibatis整合集成实例

    它提供了 SqlSessionTemplate 和 SqlSessionDaoSupport 两个工具类,方便在 Spring 环境中使用 iBATIS。 5. **Mapper 接口与 XML 映射文件**:在 iBATIS 中,业务逻辑通过 Mapper 接口实现,SQL 语句则写在对应的 ...

    ibatis批处理

    iBatis 提供了两种批处理的实现方法:在代码中直接进行循环操作和在配置文件中进行循环操作。 **1. 直接在代码中进行循环操作** 这种方法通常适用于简单的批处理需求,例如,你需要对一组数据执行相同的操作,如...

    ibatis 与spring3整合

    "Ibatis 与 Spring3 整合"这一主题,涉及到的是两个知名Java框架——Ibatis(一个轻量级的持久层框架)和Spring(一个全面的企业级应用框架)的协同工作。下面我们将深入探讨这一整合过程中的关键知识点。 Ibatis ...

    ibatis_spring源代码

    在IT行业中,`iBatis` 和 `Spring` 是两个非常重要的框架,它们分别专注于数据库访问和应用程序的全面管理。`iBatis` 是一款优秀的持久层框架,它允许开发者将SQL语句直接写在XML配置文件中,使得数据库操作更为灵活...

    Ibatis Struts1.2 Spring 2.0 整合终极版

    Ibatis Struts1.2 Spring 2.0 整合终极版,Ibatis Struts1.2 Spring 2.0 整合终极版,Ibatis Struts1.2 Spring 2.0 整合终极版

    ibatis与spring的整合

    在整合iBATIS和Spring的过程中,主要目标是利用Spring的IOC(Inversion of Control)容器来管理和协调数据访问层(DAO)以及事务处理,同时利用iBATIS作为SQL映射框架,提供灵活的数据库操作。以下将详细阐述整合的...

    Struts2+iBATIS+Spring整合

    Struts2+iBATIS+Spring整合是Java Web开发中一种常见的技术栈组合,这三种框架协同工作,可以构建出高效、灵活的企业级应用。Struts2作为MVC(Model-View-Controller)架构的一部分,主要负责处理HTTP请求,管理前端...

    SpringBatch批处理 刘相编

    《Spring Batch 批处理框架》全面、系统地介绍了批处理框架Spring Batch,通过详尽的实战示例向读者展示了Spring Batch框架对大数据批处理的基本开发能力,并对框架的架构设计、源码做了特定的剖析;在帮助读者掌握...

Global site tag (gtag.js) - Google Analytics