Mybatis批量处理
Posted qzlcl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis批量处理相关的知识,希望对你有一定的参考价值。
可以通过全局配置文件指定默认的Executor开启批量处理模式:
<setting name="defaultExecutorType" value="BATCH"/>
如果在全局配置文件中指定的话BATCH模式的话,所有的其他不需要批量处理的sql,都默认使用了Batch模式,所以正常情况下在应该在获取sqlSession的时候指定使用Batch类型的Executor,而不应该在全局配置文件配置:
@Test
public void testBatch() throws IOException
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
//可以执行批量操作的sqlSession
SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
long start = System.currentTimeMillis();
try
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
for (int i = 0; i < 10000; i++)
mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1"));
openSession.commit();
long end = System.currentTimeMillis();
System.out.println("执行时长:"+(end-start));//批量模式 执行时长4598,非批量模式 执行时长10200
finally
openSession.close();
很明显,批量模式插入有更高的效率,大概看看BatchExecutor的源码了解其原因:
@Override
public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException
final Configuration configuration = ms.getConfiguration();
final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
final BoundSql boundSql = handler.getBoundSql();
final String sql = boundSql.getSql();
final Statement stmt;
//判断MappedStatement和sql语句是否和缓存的一致
if (sql.equals(currentSql) && ms.equals(currentStatement))
int last = statementList.size() - 1;
//获取上一次已经预编译过的PreparedStatement(主要优化)
stmt = statementList.get(last);
applyTransactionTimeout(stmt);
//设置sql参数
handler.parameterize(stmt);
BatchResult batchResult = batchResultList.get(last);
//保存每次传入的参数
batchResult.addParameterObject(parameterObject);
else //首次执行
//获取连接
Connection connection = getConnection(ms.getStatementLog());
//预编译sql,获取PreparedStatement
stmt = handler.prepare(connection, transaction.getTimeout());
//设置sql参数
handler.parameterize(stmt);
//缓存当前sql语句
currentSql = sql;
//缓存MappedStatement(代表增删改查标签的所有信息)
currentStatement = ms;
//保存PreparedStatement
statementList.add(stmt);
batchResultList.add(new BatchResult(ms, sql, parameterObject));
handler.batch(stmt);
return BATCH_UPDATE_RETURN_VALUE;
主要的差别:
批量模式:(预编译sql一次==>设置参数10000次===>执行1次)
非批量模式:每插入一条记录都要完整的执行(预编译sql==>设置参数==>执行)10000次
以上是关于Mybatis批量处理的主要内容,如果未能解决你的问题,请参考以下文章