您的位置:首页 > 其它

Mybatis 批处理

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

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

Ibatis是支持批处理的:

public void batchAddExamlog(List examlogList) throws SQLException{

SqlMapClient smc=this.getSqlMapClient();

try {

smc.startTransaction();

smc.startBatch();

for (Iterator iter = examlogList.iterator(); iter.hasNext();) {

Examlog log = (Examlog) iter.next();

smc.update("insertExamlog", log);

}

smc.executeBatch();

}finally{

smc.commitTransaction();

smc.endTransaction();

}

}

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

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

总结了几种方式,大家在项目中看情况使用吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: