当前位置: 首页 > article >正文

iBatis整理——iBatis批处理实现(Sp…

从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 replyList)  
  2.   
  3.     try  
  4.         // 开始批处理  
  5.         sqlMapClient.startBatch();  
  6.   
  7.         for (Reply reply: replyList)  
  8.             // 插入操作  
  9.             sqlMapClient.insert("Reply.create"reply);  
  10.          
  11.         // 执行批处理  
  12.         sqlMapClient.executeBatch();  
  13.   
  14.     catch (Exception e)  
  15.         e.printStackTrace();  
  16.      
  17.  

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

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


我们以insert操作为例,把它们结合到一起: 
Java代码 
  1. public void create(List replyList)  
  2.   
  3.     try  
  4.         // 开始事务  
  5.         sqlMapClient.startTransaction();  
  6.         // 开始批处理  
  7.         sqlMapClient.startBatch();  
  8.   
  9.         for (Reply reply: replyList)  
  10.             // 插入操作  
  11.             sqlMapClient.insert("Reply.create"reply);  
  12.          
  13.         // 执行批处理  
  14.         sqlMapClient.executeBatch();  
  15.   
  16.         // 提交事务  
  17.         sqlMapClient.commitTransaction();  
  18.   
  19.     catch (Exception e)  
  20.         e.printStackTrace();  
  21.     finally    
  22.              try  
  23.             // 结束事务  
  24.             sqlMapClient.endTransaction();  
  25.                 catch (SQLException e)  
  26.                          e.printStackTrace();  
  27.                       
  28.        
  29.  

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

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

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

注意使用同一个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 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.             // 执行批处理  
  16.             executor.executeBatch();  
  17.   
  18.             return null 
  19.   
  20.          
  21.     });  
  22.   
  23.  

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

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

通过上述修改,最终能够解决第三种实现方式中的种种不足!  
http://www.cnblogs.com/sunwei2012/archive/2010/11/26/1888497.html
http://www.lryc.cn/news/2413369.html

相关文章:

  • linux bridge 网桥详解
  • seo原创工具_码迷SEO内参(11) 百度飓风3绝密算法解密及过百度原创的思路
  • 12种常用的LINUX版本介绍
  • Java常用类(一):HttpClient4.2 Fluent API 的简单了解
  • Microsoft .NET Framework 3.0 简介
  • 精彩---rtl8139网卡驱动程序分析
  • !DOCTYPE html PUBLIC……的组成解释
  • 作为移动开发程序员,4年小Android的心路历程,进阶学习资料!_移动应用开发学习经历(1)
  • 火车票余票问题的算法解析
  • 前端常见浏览器兼容性问题解决方案
  • mtk+android+之mt6577驱动笔记,MTK6577+Android之音频(audio)移植
  • XSS自动化入侵内网
  • 不加好友,QQ强制聊天三法
  • 国外破解站点大全
  • 【童年回忆】4399造梦西游3,各版本CE教程汇总
  • 各大网站架构总结笔记
  • 摄影基础知识学习笔记之光与色:白平衡 - 水中沙 - 博客大巴
  • 第一周:半导体器件基础(一)
  • Python之网络爬虫完全教程
  • Android 4.4 特性详解
  • c3p0的配置解释
  • 今天安装了VS2008中文版SP1。
  • Ubuntu 12.04 LTS更炫更具吸引力
  • 计算机专用英语词汇1695(持续更新)
  • oracle srvctl命令,oracle11gRAC之srvctl命令:
  • 编写我的第一个FastCGI程序
  • java.time.period计算间隔天数的问题
  • Mendix开发介绍实用篇(一)
  • Fluent UDF教程——壁面温度设定,实现动态高斯热源的施加,DEFINE_PROFILE宏讲解
  • nagios 配置详解