一、循环插入

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. React中引入外部js文件

    假设需要引入本地的一个jquery库: <script src="http://127.0.0.1:8080/plugins/jquery.min.js" type=&quo ...

  2. 给你一颗“定心丸”——记一次由线上事故引发的Log4j2日志异步打印优化分析

    一.内容提要 自知是人外有人,天外有天,相信对于Log4j2的异步日志打印早有老师或者同学已是熟稔于心,优化配置更是信手拈来,为了防止我在这里啰里八嗦的班门弄斧,我先将谜底在此公布:log4j2.as ...

  3. Win32汇编:各种语句的构造方式

    整理复习汇编语言的知识点,以前在学习<Intel汇编语言程序设计 - 第五版>时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会 ...

  4. 编译Assimp时出现“warning C4819”的解决方案

      最近又重新捣鼓起了OpenGL, 使用Assimp库加载3D模型,最新(2023/12/9)的版本是5.3.1. 使用cmake编译本是一件简单的事情: cmake . cmake --build ...

  5. SpringBoot实现统一异常处理

    目录 前言 实现步骤 定义统一响应对象类 定义业务异常枚举接口和实现 定义业务异常基类 定义全局异常处理切面 测试和验证 总结 前言 近日心血来潮想做一个开源项目,目标是做一款可以适配多端.功能完备的 ...

  6. 实现阿里云模型服务灵积 DashScope 的 Semantic Kernel Connector

    Semantic Kernel 内置的 IChatCompletionService 实现只支持 OpenAI 与 Azure OpenAI,而我却打算结合 DashScope(阿里云模型服务灵积) ...

  7. NC24605 [USACO 2011 Ope S]Corn Maze

    题目链接 题目 题目描述 This past fall, Farmer John took the cows to visit a corn maze. But this wasn't just an ...

  8. AppBox快速开发框架(开源)开发流程介绍

    pre { overflow-y: auto; max-height: 300px }   目前很多低代码平台都是基于Web用拖拽方式生成界面,确实可以极大的提高开发效率,但也存在一些问题: 大部分平 ...

  9. C++ 多线程的错误和如何避免(10)

    线程中的异常可以使用 std::rethrow_exception 抛给主线程 问题分析:一个线程中抛出的异常是没法被另一个线程捕获的.假如我们在主线程中创建一个子线程,子线程中的函数抛出了异常,主线 ...

  10. 关于Image的mode属性(多图示例)

    一.总览 Image的mode是指图片裁剪.缩放的模式,共有14个合法值,分别是: /** 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 */ scaleToFill ...