返回
Mybatis ExecutorType.BATCH 使用详解:提升 SQL 性能
java
2024-03-16 04:01:59
使用Mybatis ExecutorType.BATCH类型累积SQL语句
在Mybatis中,ExecutorType.BATCH
类型允许累积多个SQL语句,并在适当的时候一次性发送到数据库,从而提高性能。
累积语句机制
- 批处理队列:
ExecutorType.BATCH
类型打开会话时,会创建一个批处理器,该批处理器负责将SQL语句累积到队列中。 - 刷新语句: 通过调用
flushStatements()
方法,Mybatis将队列中的所有语句一次性发送到数据库。
常见的误区
在使用ExecutorType.BATCH
时,可能会遇到一些误区,导致语句无法正确累积:
- 误区一:自动生成键
- 如果SQL语句包含获取自动生成键的函数(如
SELECT LAST_INSERT_ID()
),Mybatis会在语句执行后立即向数据库发送请求。
- 如果SQL语句包含获取自动生成键的函数(如
- 误区二:缓存刷新
- 如果SQL语句更新了数据库数据,Mybatis会在语句执行后刷新缓存。
- 误区三:手动刷新
- 调用
SqlSession.commit()
或SqlSession.rollback()
也会触发语句刷新。
- 调用
解决方法
- 避免在SQL语句中使用自动生成键函数。
- 在需要时手动刷新缓存(使用
SqlSession.clearCache()
方法)。 - 在事务提交或回滚时,显式调用
SqlSession.commit()
或SqlSession.rollback()
。
修改后的测试代码
public static void main(String[] args) {
try (SqlSession sqlSession = DBConfig.getSessionFactory().openSession(ExecutorType.BATCH, true)) {
TestMapper mapper = sqlSession.getMapper(TestMapper.class);
// 累积4条插入语句
mapper.save(new TestEntity(UUID.randomUUID().toString()));
mapper.save(new TestEntity(UUID.randomUUID().toString()));
mapper.save(new TestEntity(UUID.randomUUID().toString()));
mapper.save(new TestEntity(UUID.randomUUID().toString()));
// 手动刷新缓存
sqlSession.clearCache();
// 一次性刷新所有累积的语句
List<BatchResult> batchResults = sqlSession.flushStatements();
System.out.println("批处理结果:" + batchResults);
} catch (Exception exception) {
exception.printStackTrace();
}
}
通过修改代码,我们手动刷新缓存,避免了在每个语句执行后发送请求,从而正确使用了ExecutorType.BATCH
类型。
常见问题解答
- 为什么使用
ExecutorType.BATCH
?- 减少网络开销,提高性能。
- 如何识别SQL语句需要刷新缓存?
- 它们更新了数据库数据。
- 为什么自动生成键会导致问题?
- Mybatis需要立即发送请求以获取键值。
- 除了手动刷新缓存之外,还有什么方法可以触发语句刷新?
- 提交或回滚事务。
ExecutorType.BATCH
类型有哪些局限性?- 无法处理需要获取自动生成键的SQL语句。