首页 > 其他分享 >mybatis批量插入的四种方式

mybatis批量插入的四种方式

时间:2023-06-13 19:34:36浏览次数:80  
标签:插入 JDBC 批量 userList stopWatch user statement 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(默认),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批量插入

标签:插入,JDBC,批量,userList,stopWatch,user,statement,mybatis,四种
From: https://www.cnblogs.com/sun2020/p/17478556.html

相关文章

  • Spring boot2 数据访问之Druid数据源+Mybatis
    Mybatis官方地址 1、查找Mybatis相关starter 官方文档 这里注意查找指定版本的Starter 这里以2.2.2为例,查看官方的pom.xml如下:<?xmlversion="1.0"encoding="UTF-8"?><!--Copyright2015-2022theoriginalauthororauthors.Licensedunderthe......
  • 教你如何批量关闭窗口,省时又省力!
    哈喽哈喽,大家好,今天我们来分享一个小功能。在实际的应用场景中,我们可能需要打开多个窗口,在关闭窗口时,逐个关闭窗口可能比较繁琐,而且有些窗口虽然不再显示了,但可能是隐藏的。在这种情况下,该怎么处理呢?让我们一起动手来尝试一下吧。PART1创建窗体为了方便测试,我们可以先创建多个窗体......
  • 把公司的ruoyi项目mybatis升级到mybatis-plus
    ruoyi项目mybatis升级到mybatis-plus1、ruoyi-common\pom.xml模块添加整合依赖2、ruoyi-admin文件application.yml,修改mybatis配置为mybatis-plus3、添加MybatisPlus配置MybatisPlusConfig.java4、升级后需要修改的地方4.1service接口修改4.2service实现修改4.3mapper修改1、......
  • spring boot连接Mybatis数据库的配置文件(MySql、SQLserver、Oracle)
    序号类型地址1MySQLMySQL操作之概念、SQL约束(一)2MySQLMySQL操作之数据定义语言(DDL)(二)3MySQLMySQL操作之数据操作语言(DML)(三)4MySQLMySQL操作之数据查询语言:(DQL)(四-1)(单表操作)5MySQLMySQL操作之数据查询语言:(DQL)(四-2)(多表查询)6MySQLMySQL操作之数据控制语言:(DC)(五)7MySQLMySQL操作之数......
  • PGAdmin 批量删除表
    --创建函数CREATEFUNCTIONdel_ora_table()RETURNSvoidAS$$DECLAREtmpVARCHAR(512);DECLAREnamesCURSORFORselecttablenamefrompg_tableswhereschemaname='public';BEGINFORstmtINnamesLOOPtmp:='DROPTABLE'||......
  • 如何批量修改 GitHub 代码提交作者
    批量修改GitHub代码提交作者需要进行以下步骤:首先,你需要clone远程仓库到本地,使用以下命令:gitclone<repository-url>```将`<repository-url>`替换为要克隆的仓库的URL。进入到克隆下来的代码库目录,使用以下命令查看所有提交记录:gitlog```检查要修改的提交......
  • word跨文件批量替换
    开发工具->vbs编辑新建一个模块SubWord内容替换()Dim筛选AsFileDialogDim文件名,文件AsDocumentDimpd,计数AsIntegerSet筛选器=Application.FileDialog(msoFileDialogFilePicker)With筛选器.Al......
  • 小灰灰深度学习day9——多线程读取小批量数据(这里运行的时候报错了,目前还不会解决,
    在这里先把代码放上来importtorchimporttimeimportnumpyasnpimporttorchvisionfromtorch.utilsimportdatafromtorchvisionimporttransformsfromd2limporttorchasd2ld2l.use_svg_display()#利用svg显示图片importosos.environ["KMP_DUPLICATE_LIB_OK......
  • mybatis分页插件示例
    代码示例: 注意Service中的返回值必须要和mapper中的返回值类型的@OverridepublicPageInfo<UserDO>test(ReqQueryDTOreq){PageHelper.startPage(req.getPageNumber(),req.getPageSize());List<UserDO>userDOS=mapper.pageAllSpaces(req);......
  • mybatisplus自动生成代码
    官网:https://baomidou.com/pages/24112f/1.引入依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.1</version> </dependency> <dependency> ......