小工具      在线工具  汉语词典  css  js  c++  java

Mybatis批量插入的四种方法

mybatis,java,数据库 额外说明

收录于:40天前

Mybatis批量插入的四种方式

一、循环插入

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(简单执行器),相当于JDBC的PreparedStatement.execute(sql) 执行完毕即关闭即 PreparedStatement.close()
  • REUSE(重用执行器),相当于JDBC的PreparedStatement.execute(sql) 执行完不关闭,而是将PreparedStatement存入 Map<String, Statement>中缓存,其中key为执行的sql模板;
  • BATCH(批处理执行器),相当于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();
    }
}

五、测试效率

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

@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批量插入


我是1024,一个专注Java技术、记录生活的博主。

欢迎扫描二维码关注“1024公众号”,一起学习,一起进步,看更多路,少走弯路。

在这里插入图片描述

. . .

相关推荐

额外说明

Zookeeper(zk)的监听器原理

  客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目 录节点增加删除)时,ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序。        

额外说明

解决采集文章防盗链图片不显示的问题(java)

在互联网上采集数据做应用时,我们经常会遇到目标网站图片有防盗链,导致采集文章中的图片在应用中无法预览,通常解决这个问题有2个办法: 1、采集的时候将图片下载到自己的服务器上,然后将图片路径替换为自己的图片路径,缺点是存储资源太大(费用太高),采集慢; 2

额外说明

leetcode448(查找数组:散列中所有缺失的数字)

给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。 找到所有在 [1, n] 范围之间没有出现在数组中的数字。 您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗

额外说明

用VS ATL工程开发播放Gif图片控件的步骤

1   创建解决方案 创建一个空的解决方案,名称GifSolution。将来包含控件项目和测试项目。 2   创建ATL项目 解决方案视图-右击解决方案-添加-新建项目,弹出的对话框中选ATL项目,名称为GifAnimate确定。弹出的对话框中选择DLL

额外说明

Web的四大作用域和装饰设计模式(通过拦截器来实现)

Web的四大作用域 - ServletContext: 生命周期: 一个web应用只有一个ServletContext,web应用第一次被创建的时候,ServletContext也随时创建。当服务器关闭,web应用销毁时,随着web应用的销毁而销毁 获取

额外说明

Java学习笔记3.2.1 类的封装 - 类的封装

文章目录 零、本讲学习目标 一、为什么需要封装 (一)案例演示 (二)案例分析 (三)解决方案 二、如何实现封装 (一)封装的定义 (二)封装的实现 (三)封装案例演示 (四)小结封装实现步骤 三、课后作业 任务1、计算三角形面积 任务2、创建并测试动物

额外说明

js声明数组 js数组如何获取真实对象 js数组处理null值情况 js数组通过下标赋值和push赋值的区别 loopback4的基础使用

目录 问题来源 js数组 数组通过下标赋值 数组通过push赋值 总结 loopback4 安装 创建项目 项目启动 访问项目 创建HelloController 运行访问HelloController 问题来源 今天在开发过程中,遇到一个很奇怪的问题,

额外说明

HTML学习笔记:设置超链接文本修饰

设置超链接文本修饰   1、演示效果 2、编写代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>超链接文本修饰</title> <st

额外说明

解决Windows系统缺少丢失找不到adrclient.dll文件的问题

其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个adrclient.dll文

额外说明

api-ms-win-core-threadpool-legacy-l1-1-0.dll文件丢失找不到如何解决?

其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个api-ms-win-core-threadpool-lega

ads via 小工具