面试官:如何提高MyBatis 进行批量插入的效率
创始人
2024-06-02 07:12:41
0

目录

1.使用 SQL 语句的 VALUES 关键字

2.开启批量操作功能

3.使用可重复批量操作

4.关闭自动提交

5.使用多线程并发批量操作



1.使用 SQL 语句的 VALUES 关键字

在进行批量插入时,建议使用 SQL 语句的 VALUES 关键字,将多个实体对象的值一次性插入到数据库中。这样可以避免 MyBatis 预编译语句的重复编译和解析,从而提高效率。

insert into USER (id, name) values (#{model.id}, #{model.name})

这个方法提升批量插入速度的原理是,将传统的: 

INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");

转化为:

INSERT INTO `table1` (`field1`, `field2`) 
VALUES ("data1", "data2"),
("data1", "data2"),
("data1", "data2"),
("data1", "data2"),
("data1", "data2");

2.开启批量操作功能

如果foreach后有5000+个values,这个PreparedStatement特别长,包含了很多占位符,对于占位符和参数的映射尤其耗时。并且,查阅相关资料可知,values的增长与所需的解析时间,是呈指数型增长的。

可以考虑减少一条 insert 语句中 values 的个数,最好能达到上面曲线的最底部的值,使速度最快。一般按经验来说,一次性插20~50行数量是比较合适的,时间消耗也能接受。

MyBatis文档中写批量插入的时候,是推荐使用另外一种方法。

SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);List records = getRecordsToInsert(); // not shownBatchInsert batchInsert = insert(records).into(simpleTable).map(id).toProperty("id").map(firstName).toProperty("firstName").map(lastName).toProperty("lastName").map(birthDate).toProperty("birthDate").map(employed).toProperty("employed").map(occupation).toProperty("occupation").build().render(RenderingStrategy.MYBATIS3);batchInsert.insertStatements().stream().forEach(mapper::insert);session.commit();
} finally {session.close();
}

即基本思想是将 MyBatis session 的 executor type 设为 Batch ,然后多次执行插入语句。就类似于JDBC的下面语句一样。

Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=false&rewriteBatchedStatements=true","root","root");
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement("insert into tb_user (name) values(?)");
for (int i = 0; i < stuNum; i++) {ps.setString(1,name);ps.addBatch();
}
ps.executeBatch();
connection.commit();
connection.close();

经过试验,使用了 ExecutorType.BATCH 的插入方式,性能显著提升,不到 2s 便能全部插入完成。

如果MyBatis需要进行批量插入,推荐使用 ExecutorType.BATCH 的插入方式,如果非要使用 的插入的话,需要将每次插入的记录控制在 20~50 左右。

MyBatis-Plus作为MyBatis的增强,它的批量操作executor type就是Batch。

3.使用可重复批量操作

可重复批量操作是一种特殊的批量操作模式,可以在多次执行相同 SQL 语句时,避免重复编译和解析 SQL 语句,从而提高效率。可以通过调用 SqlSession 的 flushStatements 方法,来实现可重复批量操作。

4.关闭自动提交

在进行批量操作时,建议关闭自动提交功能,以减少数据库事务的提交次数,提高性能。可以通过在配置文件中设置 autoCommit 属性为 false 来关闭自动提交功能。

5.使用多线程并发批量操作

如果需要插入的数据量非常大,可以考虑使用多线程并发批量操作的方式,将数据分成多个批次进行插入。可以使用 Java 的线程池和 MyBatis 的 BatchExecutor 类,实现多线程并发批量操作。

相关内容

热门资讯

庆祝元旦演出的主持词 庆祝元旦演出的主持词范文(通用8篇)  主持词是主持人在节目进行过程中用于串联节目的串联词。时代不断...
新郎致辞 新郎致辞(精选18篇)  在日常学习、工作抑或是生活中,大家总免不了要接触或使用致辞吧,致辞具有针对...
舞蹈串词 舞蹈串词a:尊敬的各位领导 尊敬的各位领导 b:敬爱的老师 敬爱的老师 c:亲爱的同学们 亲爱的同学...
电影《北京爱情故事》经典台词 电影《北京爱情故事》经典台词1、我们的生命中总会出现这样的一个瞬间,某时某地你会遇见某个人。2、结婚...
晨会的主持词怎么写 晨会的主持词怎么写  主持人在台上所表演的主持词,则这样集会的灵魂之所在。下面小编整理的晨会的主持词...
圣诞晚会主持词结束语 圣诞晚会主持词结束语(精选11篇)  主持词要注意活动对象,针对活动对象写相应的主持词。在当下的中国...
母亲节感恩的心主持词 母亲节感恩的心主持词  主持词需要富有情感,充满热情,才能有效地吸引到观众。随着社会一步步向前发展,...
蓝色大门经典台词 蓝色大门经典台词  1、林月珍:张士豪他每天晚上,都会偷偷来游泳,他是游泳队的。  孟克柔:看什么?...
宫崎骏《起风了》的经典台词 宫崎骏《起风了》的经典台词  1、起风了,唯有努力生存。  2、再没有什么比幸福的回忆更妨碍幸福的了...
公司成立周年庆典主持词 公司成立周年庆典主持词  主持词可以采用和历史文化有关的表述方法去写作以提升活动的文化内涵。在各种集...
辩论赛主持词 关于辩论赛主持词4篇  契合现场环境的主持词能给集会带来双倍的效果。在当下的中国社会,各种集会中主持...
同学三十周年聚会主持词 同学三十周年聚会主持词尊敬的各位老师、亲爱的同学们:  大家好!  风霜雪雨三十载,师生情谊天长地久...
六一儿童节活动主持稿 有关六一儿童节活动主持稿(通用7篇)  随着社会一步步向前发展,越来越多地方需要用到主持稿,主持稿的...
春到福来春晚主持词 春到福来春晚主持词  节目:《春到福来》  朱军:春到福来,春上春伦云天外  周涛:春到福来,春向黄...
平安夜晚会主持词 平安夜晚会主持词  主持词是主持人在节目进行过程中用于串联节目的串联词。在一步步向前发展的社会中,司...
农村简单结婚典礼主持词 农村简单结婚典礼主持词  一、结婚典礼的内容简介  在世界各国大部分的文化里,会发展出一些结婚上的传...
大话西游最经典的台词 大话西游最经典的台词  大话西游是周星驰主演的一部经典的喜剧爱情片。里面的台词曾感染了无数观众。以下...
公司会议主持词 关于公司会议主持词(通用5篇)  主持词要把握好吸引观众、导入主题、创设情境等环节以吸引观众。在如今...
生日派对会的主持串词 关于生日派对会的主持串词  作者:赵可心  题目:我非常高兴  要求:用普通话  环节:  1、 开...
少先队员宣誓主持词 少先队员宣誓主持词(精选8篇)  主持词已成为各种演出活动和集会中不可或缺的一部分。我们眼下的社会,...