zoukankan      html  css  js  c++  java
  • iBatis整理——Spring环境下批处理实现

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

    大概是太久没有写Dao了,这部分真的忘得太干净了。iBatis整理——Spring环境下批处理实现 

    从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()方法,将会造成异常! 

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


    4.基于回调方式的Spring+iBatis实现 
    如果观察过Spring的源代码,你一定知道,Spring为了保持事务统一控制,在实现ORM框架时通常都采用了回调模式,从而避免了事务代码入侵的可能!iBatis整理——Spring环境下批处理实现 
    修改后的代码如下: 
    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!iBatis整理——Spring环境下批处理实现 
    简述: 
    1. SqlMapClientCallback 回调接口
    2. doInSqlMapClient(SqlMapExecutor executor) 回调实现方法
    3. DataAccessException 最终可能抛出的异常

    通过上述修改,最终能够解决第三种实现方式中的种种不足!iBatis整理——Spring环境下批处理实现 

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

  • 相关阅读:
    9、UmbracoNewsSite:分页
    7、UmbracoNewsSite:新闻详情页
    6、UmbracoNewsSite:添加新闻分类
    5、UmbracoNewsSite:添加css和js文件
    3、UmbracoNewsSite:文档类型设置
    书单
    文章
    Django-rest framework框架
    Django框架
    前端快速入门
  • 原文地址:https://www.cnblogs.com/liuzhuqing/p/7480168.html
Copyright © 2011-2022 走看看