Mybatis 批处理



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






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






Ibatis是支持批处理的:






1. public void batchAddExamlog(List examlogList) throws
2. this.getSqlMapClient();                                           
3. try
4.         smc.startTransaction();                                                          
5.         smc.startBatch();                                                                                                                                                                                      
6. for
7.             Examlog log = (Examlog) iter.next();  
8. "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,一个使用批处理方式,一个不使用批处理,程序中适时而用。
 
 

 
 
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() 获得影响结果
 
 

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

 
 

 
 
总结了几种方式,大家在项目中看情况使用吧。
         
 
有的时候,我们需要一次性插入很多的数据或者一次性更新、删除很多的数据,那么为了提高效率,我们需要使用批处理来完成。以下将讨论Mybatis+Spring如何使用批处理。
 
 

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

 
 
Ibatis是支持批处理的:
 
 

 
 
 
  
1. public void batchAddExamlog(List examlogList) throws
2. this.getSqlMapClient();                                           
3. try
4.         smc.startTransaction();                                                          
5.         smc.startBatch();                                                                                                                                                                                      
6. for
7.             Examlog log = (Examlog) iter.next();  
8. "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,一个使用批处理方式,一个不使用批处理,程序中适时而用。
 
 

 
 
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() 获得影响结果






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









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