一、循环插入

public void insert(List<User> userList) {
userList.forEach(user -> userDao.insert(user));
}
<insert id="insert">
INSERT INTO `demo`.`user` (`username`, `address`, `remark`, `age`, `create_time`)
VALUES (#{user.username,jdbcType=VARCHAR},
#{user.address,jdbcType=VARCHAR},
#{user.remark,jdbcType=VARCHAR},
#{user.age,jdbcType=INTEGER},
now())
</insert>

二、批量插入

这里是否选择100个为一组还是200或者其他,需要进行多次测试

public void insertBatch(List<User> userList) {
List<List<User>> partition = ListUtil.partition(userList, 100);
for (List<User> users : partition) {
userDao.insertBatch(users);
}
}
<insert id="insertBatch">
INSERT INTO `demo`.`user` (`username`, `address`, `remark`, `age`, `create_time`)
VALUES
<foreach collection="users" index="" item="user" separator=",">
(#{user.username,jdbcType=VARCHAR},
#{user.address,jdbcType=VARCHAR},
#{user.remark,jdbcType=VARCHAR},
#{user.age,jdbcType=INTEGER},
now())
</foreach> </insert>

三、BatchExecutor插入

mybatis提供了三种sql执行器,分别是SIMPLE(默认),REUSE,BATCH:

  • SIMPLE(SimpleExecutor),相当于JDBC的PreparedStatement.execute(sql) 执行完毕即关闭即 PreparedStatement.close()
  • REUSE(ReuseExecutor),相当于JDBC的PreparedStatement.execute(sql) 执行完不关闭,而是将PreparedStatement存入 Map<String, Statement>中缓存,其中key为执行的sql模板;
  • BATCH(BatchExecutor),相当于JDBC语句的 PreparedStatement.addBatch(sql),即仅将执行SQL加入到批量计划但是不真正执行, 所以此时不会执行返回受影响的行数,而只有执行PreparedStatement.execteBatch()后才会真正执行sql
@Autowired
private SqlSessionFactory sqlSessionFactory; @Override
public void insertBatchType(List<User> userList) {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
UserDao mapper = sqlSession.getMapper(UserDao.class);
try {
for (User user : userList) {
mapper.insert(user);
}
sqlSession.commit();
} catch (Exception e) {
System.out.println("批量导入数据异常,事务回滚");
sqlSession.rollback();
} finally {
sqlSession.close();
}
}

四、JDBC插入

当然也可以使用原生的JDBC的方式进行批量插入,使用` statement.addBatch();的方式,也是很快的

@Resource(name = "dataSource")
private DataSource dataSource; @Override
public void insertJdbc(List<User> userList) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
String sql = "INSERT INTO `user` (`username`, `address`, `remark`, `age`, `create_time`) " +
"VALUES (?,?,?,?,now()) ";
statement = connection.prepareStatement(sql);
for (User user : userList) {
statement.setString(1, user.getUsername());
statement.setString(2, user.getAddress());
statement.setString(3, user.getRemark());
statement.setInt(4, user.getAge());
statement.addBatch();
}
statement.executeBatch();
connection.commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
statement.close();
connection.close();
}
}

五、测试效率

准备60w条数据,分别测试以上四种插入方式的效率:

@Test
public void test_for_user() throws SQLException {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 600000; i++) {
User user = new User();
user.setUsername("张三" + i);
user.setAddress("上海" + i);
user.setRemark("备注" + i);
user.setAge(i);
userList.add(user);
} StopWatch stopWatch = new StopWatch();
stopWatch.start("循环插入");
userService.insert(userList);
stopWatch.stop();
System.out.println(stopWatch.getLastTaskName() + ":" + stopWatch.getLastTaskTimeMillis()); stopWatch.start("批量插入");
userService.insertBatch(userList);
stopWatch.stop();
System.out.println(stopWatch.getLastTaskName() + ":" + stopWatch.getLastTaskTimeMillis()); stopWatch.start("BatchType插入");
userService.insertBatchType(userList);
stopWatch.stop();
System.out.println(stopWatch.getLastTaskName() + ":" + stopWatch.getLastTaskTimeMillis()); stopWatch.start("JDBC-BatchType插入");
userService.insertJdbc(userList);
stopWatch.stop();
System.out.println(stopWatch.getLastTaskName() + ":" + stopWatch.getLastTaskTimeMillis()); }
循环插入:1272111
批量插入:27990
BatchType插入:28143
JDBC-BatchType插入:15976

测试结果还是显而易见的,循环插入>批量插入>BatchType插入>JDBC批量插入

mybatis批量插入的四种方式的更多相关文章

  1. mybatis中批量插入的两种方式(高效插入)

    MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用 ...

  2. mybatis批量保存的两种方式(高效插入)

    知识点:mybatis中,批量保存的两种方式 1.使用mybatis foreach标签 2.mybatis ExecutorType.BATCH 参考博客:https://www.jb51.net/ ...

  3. CSS插入的四种方式

    一.什么是CSS CSS(Cascading style sheets  层叠样式表),CSS可以用以为网页构建样式表,通过样式表来达到对网页进行美化的效果.所谓层叠可以将网页想象成一层层的结构,高层 ...

  4. MyBatis_动态sql_foreach_mysql下foreach批量插入的两种方式

    方法1: 笔记要点出错分析与总结工程组织数据库组织0.重新修改Bean类    修改1.定义接口 //批量插入 public void addEmps(@Param("emps") ...

  5. mybatis批量更新的几种方式和性能对比

    https://blog.csdn.net/csdnbeyoung/article/details/106258611

  6. MyBatis 批量插入数据的 3 种方法!

    批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于<MyBatis Plus 批量数据插入功能,yyds!>的文章,但评论区的反馈不是很好,主要有两个问题:第一,对 ...

  7. C#批量插入数据到Sqlserver中的四种方式

    我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...

  8. C#_批量插入数据到Sqlserver中的四种方式

    先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记 ...

  9. C#批量插入数据到Sqlserver中的四种方式 - 转

    先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记 ...

  10. java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...

随机推荐

  1. go中bufio使用小结

    bufio 前言 例子 bufio 源码解析 Reader对象 实例化 ReadSlice ReadString ReadLine Peek Scanner Give me more data Err ...

  2. 4.9 C++ Boost 命令行解析库

    命令行解析库是一种用于简化处理命令行参数的工具,它可以帮助开发者更方便地解析命令行参数并提供适当的帮助信息.C++语言中,常用的命令行解析库有许多,通过本文的学习,读者可以了解不同的命令行解析库和它们 ...

  3. CE修改器入门:浮点数的扫描

    在前面的教程中我们使用4字节的方式进行扫描,但有些游戏使用了"浮点数"来存储数值,浮点数是带有小数点的数值(如 5.12 或 11321.1),正如本关中的健康和弹药,两者都以浮点 ...

  4. 音频处理实用AI工具

    最近在做音频处理相关的工作,主要有以下几个好用的工具. 1. 语音转文字--whisper 这是一款由OpenAI开发的语音转文字工具,项目地址位于:openai/whisper. 这个工具是用来生成 ...

  5. 如何进行IIS性能优化,提高应用并发能力

    2021-03-05 先附上IIS的官方文档,如果你的英文阅读能力不错的话,直接阅读官方文档,更加清楚明白: https://docs.microsoft.com/zh-cn/iis/get-star ...

  6. (C语言)每日代码||2023.12.25||函数传参,传入数组时传递的是数组首元素地址

    向函数传入某数组时,可以在函数内修改该数组的元素. #include <stdio.h> void test(char* p, char arr[]) { *p = 'h';//能改变 * ...

  7. Linux-nmon系统监控工具

    一.Nmon介绍 Nmon得名于 Nigel 的监控器,是IBM的员工 Nigel Griffiths 为 AIX 和 Linux 系统开发的,使用 Nmon 可以很轻松的监控系统的 CPU.内存.网 ...

  8. 【译】.NET 8 网络改进(二)

    原文 | Máňa,Natalia Kondratyeva 翻译 | 郑子铭 修改 HttpClient 日志记录 自定义(甚至简单地关闭)HttpClientFactory 日志记录是长期请求的功能 ...

  9. 【JS】强化Promise理解,从零手写属于自己的Promise.all与Promise.race

    壹 ❀ 引 在一个思路搞定三道Promise并发编程题,手摸手教你实现一个Promise限制器一文中,我们在文章结尾留了一个疑问,关于第三题的实现能否解决当每次调用时间都不相等的情况(比如第二次调用要 ...

  10. 从零开始的react入门教程(四),了解常用的条件渲染、列表渲染与独一无二的key

    壹 ❀ 引 在从零开始的react入门教程(三),了解react事件与使用注意项一文中,我们了解了react中事件命名规则,绑定事件时对于this的处理,以及事件中可使用的e对象.那么这篇文章中我们来 ...