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

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

从4个层面分析这部分实现:

  1. iBatis的基本实现
  2. 基于事务的iBatis的基本实现
  3. 基于事务的Spring+iBatis实现
  4. 基于回调方式的Spring+iBatis实现

1.iBatis的基本实现 
iBatis通过SqlMapClient提供了一组方法用于批处理实现:

  1. startBatch() 开始批处理
  2. executeBatch() 执行批处理

代码如下:

Java代码 
  1. public void create(List<Reply> replyList) {
  2. try {
  3. // 开始批处理
  4. sqlMapClient.startBatch();
  5. for (Reply reply: replyList) {
  6. // 插入操作
  7. sqlMapClient.insert("Reply.create", reply);
  8. }
  9. // 执行批处理
  10. sqlMapClient.executeBatch();
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. }

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

2.基于事务的iBatis的基本实现 
事务处理:

  1. startTransaction() 开始事务
  2. commitTransaction() 提交事务
  3. endTransaction() 结束事务

我们以insert操作为例,把它们结合到一起:

Java代码 
  1. public void create(List<Reply> replyList) {
  2. try {
  3. // 开始事务
  4. sqlMapClient.startTransaction();
  5. // 开始批处理
  6. sqlMapClient.startBatch();
  7. for (Reply reply: replyList) {
  8. // 插入操作
  9. sqlMapClient.insert("Reply.create", reply);
  10. }
  11. // 执行批处理
  12. sqlMapClient.executeBatch();
  13. // 提交事务
  14. sqlMapClient.commitTransaction();
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. } finally {
  18. try {
  19. // 结束事务
  20. sqlMapClient.endTransaction();
  21. } catch (SQLException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }

replyList是一个List,要把这个List插入到数据库,就需要经过这三个步骤:

  1. 开始批处理 startBatch()
  2. 插入      insert()
  3. 执行批处理 executeBatch()

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

3.基于事务的Spring+iBatis实现

Java代码 
  1. public void create(List<Reply> replyList) {
  2. if (!CollectionUtils.isEmpty(replyList)) {
  3. // 注意使用同一个SqlMapClient会话
  4. SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient();
  5. try {
  6. // 开始事务
  7. sqlMapClient.startTransaction();
  8. // 开始批处理
  9. sqlMapClient.startBatch();
  10. for (Reply reply : replyList) {
  11. // 插入操作
  12. sqlMapClient.insert("Reply.create", reply);
  13. }
  14. // 执行批处理
  15. sqlMapClient.executeBatch();
  16. // 提交事务 交给Spring统一控制
  17. // sqlMapClient.commitTransaction();
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. } finally {
  21. try {
  22. // 结束事务
  23. sqlMapClient.endTransaction();
  24. } catch (SQLException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  29. }

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

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

4.基于回调方式的Spring+iBatis实现 
如果观察过Spring的源代码,你一定知道,Spring为了保持事务统一控制,在实现ORM框架时通常都采用了回调模式,从而避免了事务代码入侵的可能! 
修改后的代码如下:

Java代码 
  1. @SuppressWarnings("unchecked")
  2. public void create(final List<Reply> replyList) {
  3. // 执行回调
  4. sqlMapClientTemplate.execute(new SqlMapClientCallback() {
  5. // 实现回调接口
  6. public Object doInSqlMapClient(SqlMapExecutor executor)
  7. throws SQLException {
  8. // 开始批处理
  9. executor.startBatch();
  10. for (Reply reply : replyList) {
  11. // 插入操作
  12. executor.insert("Reply.create", reply);
  13. }
  14. // 执行批处理
  15. executor.executeBatch();
  16. return null;
  17. }
  18. });
  19. }

注意,待遍历的参数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比较得宠!

转载于:https://www.cnblogs.com/sunwei2012/archive/2010/11/26/1888497.html

iBatis整理——iBatis批处理实现(Spring环境)相关推荐

  1. 紧急整理了 20 道 Spring Boot 面试题,我经常拿来面试别人

    转载自  紧急整理了 20 道 Spring Boot 面试题,我经常拿来面试别人 面试了一些人,简历上都说自己熟悉 Spring Boot, 或者说正在学习 Spring Boot,一问他们时,都只 ...

  2. ibatis(2)ibatis是什么

    [0]README 1)本文部分内容转自 "ibatis in action",旨在 review "ibatis是什么" 的相关知识: 2)intro to ...

  3. 大数据批处理框架Spring Batch 的全面解析

    如今微服务架构讨论的如火如荼.但在企业架构里除了大量的OLTP交易外,还存在海量的批处理交易.在诸如银行的金融机构中,每天有3-4万笔的批处理作业需要处理.针对OLTP,业界有大量的开源框架.优秀的架 ...

  4. Spring Boot 集成 批处理框架Spring batch

    Spring Batch是一个轻量级的框架,完全面向Spring的批处理框架,用于企业级大量的数据读写处理系统.以POJO和Spring 框架为基础,包括日志记录/跟踪,事务管理. 作业处理统计工作重 ...

  5. Spring环境搭建,IoC容器初体验~

    由于最近的任务是关于IoC配置文件格式的转换,所以需要从Spring的IoC容器开始学起,今天根据网上的介绍搭建了Spring环境,并对其IoC容器进行了初体验.文章中涉及到的软件以及推荐的一本关于S ...

  6. spring boot api文档_精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用

    一.什么是 RestTemplate? RestTemplate是执行HTTP请求的同步阻塞式的客户端,它在HTTP客户端库(例如JDK HttpURLConnection,Apache HttpCo ...

  7. ibatis(0)ibatis 与 mybatis 简述

    [0]README: 1)本文旨在给出 ibatis 与 mybatis 简述,简述内容转自 如下链接: [1]main contents 1)apache offical declarationht ...

  8. spring 环境配置

    搭建Spring开发环境并编写第一个Spring小程序 一.前面,我写了一篇Spring框架的基础知识文章,里面没讲到如何配置Spring开发环境,今天就来讲一下,如果大家不知道怎么下载Spring软 ...

  9. IoC、Spring 环境搭建、Spring 创建对象的三种方式、DI

    二.IoC 中文名称:控制反转 英文名称:(Inversion of Control) 3.I oC 是什么? 3.1 IoC 完成的事情原先由程序员主动通过 new 实例化对象事情,转交给 Spri ...

最新文章

  1. 从理论到实践: ORB-SLAM3 Initializer完全解读
  2. python做一个系统-用python做一个系统监控程序
  3. mysql图标_MySQL 支持 emoji 图标存储
  4. Java 包(package)
  5. C++中如何定义某个数组的引用?
  6. DDD理论学习系列(4)-- 领域模型
  7. vue 监听浏览器页面关闭_前方高能,这是最新的一波Vue实战技巧,不用则已,一用惊人...
  8. Centos安装(更新)git(亲测有效)
  9. 上偏续关系哈斯图_偏序集的哈斯图G(A)跟A上的偏序关系≤的关系图G(≤)是一 一对应的,相互确定。...
  10. 数字孪生技术方案下的智慧城市建设治理体系优势
  11. matlab最小二乘法解超定方程,超定方程和最小二乘法
  12. Vuforia SDK导入问题Vuforia.UnityExtensions Consider removing one of the references or sign the assembl
  13. 随身WiFi刷debian固件
  14. 爱普生打印机无法正常工作的解决方法
  15. 港科夜闻|香港科大唐本忠院士团队整合最新研究成果:刺激响应型聚集诱导发光材料...
  16. 《工程伦理》网课第十章课后习题答案
  17. ros基础概念以及第一个项目
  18. 12米数字高程DEM现已上线!附DEM专题图制作教程
  19. 凡是过往,皆为序章,致敬2021,迎接2022!
  20. JavaScript状态机处理字符串

热门文章

  1. 苹果手机(ios)拍照上传图片旋转90度问题---java后台处理
  2. 对我国域名系统安全问题的思考
  3. java enum(枚举)的使用
  4. Mysql定期自动备份
  5. Project Management - 3) Manage Your Meetings
  6. SpringMVC源码阅读:过滤器
  7. Vue2.0 + ElementUI 手写权限管理系统后台模板(一)——简述
  8. less background url相对路径取不到编译报错问题
  9. 从字符串指定位置删除指定个数的字符
  10. 超酷的实时颜色数据跟踪javascript类库 - Tracking.js