【MyBatis】批量插入
1.背景
项目中需要基于批量插入数据,经过比较使用SqlSession批量插入。
2.使用
引用【MyBatis】几种批量插入效率的比较 - 掘金 (juejin.cn)
- 1.注意:数据库
url
后面跟了一段rewriteBatchedStatements=true
,MySql
的JDBC
连接的url
中要加rewriteBatchedStatements
参数,并保证5.1.13
以上版本的驱动,才能实现高性能的批量插入。MySql JDBC
驱动在默认情况下会无视executeBatch()
语句,把我们期望批量执行的一组sql
语句拆散,一条一条地发给MySql
数据库,批量插入实际上是单条插入,直接造成较低的性能。只有把rewriteBatchedStatements
参数置为true
, 驱动才会帮你批量执行SQL
。这个选项对INSERT
/UPDATE
/DELETE
都有效。
spring:
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3305/se?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
username: root
password: root
# maximum-pool-size: 15
- 2.使用过程
SqlSessionFactory sqlSessionFactory = Application.getBean(MyBatisConfig.class).sqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
Application.destroy(MyBatisConfig.class.getName());
RealDataBodyAccMapper aMapper = sqlSession.getMapper(RealDataBodyAccMapper.class);
RealDataBodyVelocityMapper vMapper = sqlSession.getMapper(RealDataBodyVelocityMapper.class);
for (int i = 0; i < tmpA.size(); i++) {
aMapper.insertSelective(tmpA.get(i));
if (i % 1000 == 999) {
sqlSession.commit();
sqlSession.clearCache();
}
}
sqlSession.commit();
sqlSession.clearCache();
for (int i = 0; i < tmpV.size(); i++) {
vMapper.insertSelective(tmpV.get(i));
if (i%1000==999){
sqlSession.commit();
sqlSession.clearCache();
}
}
sqlSession.commit();
sqlSession.clearCache();
sqlSession.close();
使用注意:
- 必须sqlSession.close();否则线程池会出现泄露。(此外可以配置数据库池各种参数maximum-pool-size: 15)
- 可以使用一定数量的插入
if (i%1000==999){
sqlSession.commit();
sqlSession.clearCache();
}
- 不能将插入语句一起使用,否则会无视executeBatch(),一条一条语句插入,插入变慢。
for (int i = 0; i < tmpA.size(); i++) {
aMapper.insertSelective(tmpA.get(i));
vMapper.insertSelective(tmpV.get(i));
if (i % 1000 == 999) {
sqlSession.commit();
sqlSession.clearCache();
}
}
sqlSession.commit();
sqlSession.clearCache();