面试官:如何提高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 类,实现多线程并发批量操作。

相关内容

热门资讯

感谢父母诗歌 感谢父母诗歌  在我们的生命中最应该感谢的就是我们的父母,那么关于感谢父母的诗歌有哪些呢?下面就和小...
描写春天的诗歌范文5篇 诗歌是用高度凝练的语言,形象表达作者丰富情感,集中反映社会生活并具有一定节奏和韵律的文学体裁。下面是...
描写失败的中英文诗歌 描写失败的中英文诗歌  THE SIGNIFICANCE OF FAILURE  Robert H....
雪落无声诗歌 雪落无声诗歌大全  在日常的学习、工作、生活中,说到诗歌,大家肯定都不陌生吧,诗歌以强烈的节奏、美妙...
如果我再遇见你诗歌 如果我再遇见你诗歌  那年那月的那天  我站在远方  远远地望着你向我走来  带着旧的故事  以及深...
那是远方为诗歌   世界之大  为何枯竭  内心之小  是多么的孤寂  远处澎湃的声音  回荡在门前的石阶  射手座...
关于歌唱建党100年新时代的... 从1921年筚路蓝缕到2021年蓬勃壮大,党以矢志不渝的奋斗和创造走过了100年,开创出新的局面。那...
为爱转身诗歌 为爱转身诗歌  我用我的双手  托起你骄傲的资本  你俯视着一切  风光无限  却不知我早已汗流浃背...
现代有人生哲理的诗歌 现代有人生哲理的诗歌  用高度凝练的语言,形象表达作者丰富情感,集中反映社会生活并具有一定节奏和韵律...
冬晚对雪忆胡居士家 阅读答案 冬晚对雪忆胡居士家 阅读答案 冬晚对雪忆胡居士家 阅读答案,此诗是一首五言律诗,作者是唐代著名的大诗...
写给父母诗歌 关于写给父母诗歌  父母对我们的恩情是永远也还不清的,让我们来看看有哪些诗歌是赞美父母的,下面是小编...
那一年诗歌 那一年诗歌那一年诗歌1  夜已经深了,黑夜不再会有璀璨的光  我知道  这颗星星离我一泓水的距离  ...
我们的现代诗歌 我们的现代诗歌  我们,  在一次次迷失中寻找自我,  在一次次绝望中重燃希望,  在一次次挫折中永...
形容女人消瘦的经典诗句 形容女人消瘦的经典诗句  衣带渐宽终不悔,为伊消得人憔悴。—柳永《凤栖梧》  二死生契阔,与子成说。...
收拢一季思绪抒情散文 收拢一季思绪抒情散文  念秋,朴实而又宁静;以冲淡了的心情,细数生活纹路,悟思;习惯结一段幽怨,不深...
描写大海景色的古诗句 描写大海景色的古诗句  白色的浪花,从遥远的大海深处涌向岸边。一浪高过一浪,后浪推前浪,这么美的景象...
描写好心情的诗句 描写好心情的诗句  水是眼波横白日放歌须纵酒,青春做伴好还乡  白云山头云欲立,白云山下呼声急,枯木...
相伴一生的唯美诗句 相伴一生的唯美诗句  在学习、工作乃至生活中,大家都接触过比较经典的诗句吧,诗句是诗的.句子,泛指诗...
鲁迅与胡适的爱恨情仇 鲁迅与胡适的爱恨情仇  近段时间,系统地读了些鲁迅与胡适的文集,以及介绍两位先生的传记文章。走进他们...
蝉的诗句 关于蝉的诗句  1、莫侵残日噪,正在异乡听。——五代楚·刘昭禹《闻蝉》  2、本以高难饱,徒劳恨费声...