Mybatis 批处理

有的时候,我们需要一次性插入很多的数据或者一次性更新、删除很多的数据,那么为了提高效率,我们需要使用批处理来完成。以下将讨论Mybatis+Spring如何使用批处理。

首先应该知道Mybatis是Ibatis的升级版,比Ibatis性能更好,这是我采用Mybatis的原因。

Ibatis是支持批处理的

  1. public void batchAddExamlog(List examlogList) throws SQLException{                   
  2.     SqlMapClient smc=this.getSqlMapClient();                                           
  3.     try {                                                                              
  4.         smc.startTransaction();                                                          
  5.         smc.startBatch();                                                                                                                                                                                      
  6.         for (Iterator iter = examlogList.iterator(); iter.hasNext();) {  
  7.             Examlog log = (Examlog) iter.next();  
  8.             smc.update("insertExamlog", log);  
  9.         }                                                                              
  10.         smc.executeBatch();                                                              
  11.     }finally{                                                                          
  12.         smc.commitTransaction();                                                         
  13.         smc.endTransaction();                                                            
  14.     }                                                                                  
  15. }   


Mybatis接口实现批处理:

sessionFactory.openSession(ExecutorType.BATCH,true);//得到session,用于批量update


以上两种,他们都可以实现批处理。
但是当 Mybatis + Spring集成,且由Spring控制事务时,Mybatis这种批处理是不能使用的。
因为sessionFactory.openSession(ExecutorTypetype);方法会创建一个新的数据库连接,该连接不受Spring控制,将导致Spring的事务控制失效,它无法利用与当前线程绑定的session。

再看其他方式:

1、Mybatis主配置文件中,加入下面代码:
<configuration>
<settings>
<setting name="defaultExecutorType" value="BATCH"/>
</settings>
</configuration>
 -- 这是个总配置,所有操作都会生效,在任何一个事务中做的更改,在事务结束时提交,该事务内无法读取自己的操作结果。
 -- 它会导致所有方法 insert 无法返回id,update/delete 无法得到影响行数,所以、这个全局设置并不好。

2、配合(1)使用SqlSessionUtils.getSqlSession(sessionFactory).commit();

 -- 虽然数据在事务内提交了,但是依然无法获得自增id

3、mapper文件中使用foreach标签拼装语句

 -- 但是sql语句有长度限制,小数据量可以(当然也可以从数据库设置sql最长限制)。

4、获得当前连接,使用jdbc进行批处理操作。

 -- 这也不好,sql需要写在其他地方,不能写在Mapper文件中。

5、从Spring上下文中,实例化两个SqlSessionTemplate,一个使用批处理方式,一个不使用批处理,程序中适时而用。

 -- 无法获得自增id,且一个事务中不能同时使用两个SqlSessionTemplate。

6、从源代码,扩展自己的批处理实现。
1、BatchExecutor类的public List<BatchResult> doFlushStatements() throws SQLException方法最终执行批量操作,它将返回影响信息。
2、BatchExecutor.doFlushStatements() 方法在 Executor.commit() 方法中被调用。
3、Executor.commit() 在 SqlSession 中调用。
4、SqlSessionFactory 负责创建 SqlSession。

扩展SqlSessionFactory 创建我们定义的 MySqlSession,MySqlSession 最终可以调用到BatchExecutor.doFlushStatements() 获得影响结果

 -- 这种方式需要扩展源码。


总结了几种方式,大家在项目中看情况使用吧。



你可能感兴趣的:(spring,sql,数据库,ibatis,session,insert)