176142998

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  116 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks
从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.   
  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<Reply> 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<Reply> 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<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.             // 执行批处理   
  16.             executor.executeBatch();   
  17.   
  18.             return null;   
  19.   
  20.         }   
  21.     });   
  22.   
  23. }  

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

这样做,就将事务处理的控制权完全交给了Spring!
简述:
  1. SqlMapClientCallback 回调接口
  2. doInSqlMapClient(SqlMapExecutor executor) 回调实现方法
  3. DataAccessException 最终可能抛出的异常
posted on 2011-04-21 10:15 飞飞 阅读(935) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: