0
点赞
收藏
分享

微信扫一扫

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


 

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


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

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

 


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

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

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

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

代码如下: 


Java代码  

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

1. public void
2.   
3. try
4. // 开始批处理
5.         sqlMapClient.startBatch();  
6.   
7. for
8. // 插入操作
9. "Reply.create", reply);  
10.         }  
11. // 执行批处理
12.         sqlMapClient.executeBatch();  
13.   
14. catch
15.         e.printStackTrace();  
16.     }  
17. }


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

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

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

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


Java代码  

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

注意使用同一个sqlMapClient: 

SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient(); 

如果直接sqlMapClientTemplate执行insert()方法,将会造成异常! 


想想,还有什么问题?其实问题很明显,虽然解决了批处理实现的问题,却造成了事务代码入侵的新问题。

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

 这么做,有点恶心! 
除此之外,异常的处理也很恶心,不能够简单的包装为 DataAccessException 就无法被Spring当作统一的数据库操作异常做处理。 


4.基于回调方式的Spring+iBatis实现 

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

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

 

修改后的代码如下: 

Java代码  


       
1. @SuppressWarnings("unchecked")  
2. public void create(final
3. // 执行回调
4. new
5. // 实现回调接口
6. public
7. throws
8. // 开始批处理
9.             executor.startBatch();  
10. for
11. // 插入操作
12. "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!

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

 

简述: 

  1. SqlMapClientCallback 回调接口
  2. doInSqlMapClient(SqlMapExecutor executor) 回调实现方法
  3. DataAccessException 最终可能抛出的异常

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

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

 


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

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

 还是Hibernate比较得宠!

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

 


做个小记录,呵呵!

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

举报

相关推荐

0 条评论