【Mybatis】使用批处理优化百万数据量插入

当使用MyBatis进行批量插入时,如果数据量过大,超过MySQL的最大SQL执行限制(4M),会导致错误。为了解决这个问题,文章提出了采用Guava库进行数据分片,然后循环插入的方法,将大列表拆分成小块进行批量操作。这种方法成功地将一次插入32w数据的时间从90分钟优化到了18秒,显著提升了性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xingceng.bimsys.dao.BimModelDataDao">
    <insert id="saveBatch" parameterType="java.util.List">
        INSERT INTO `bimangle_data`(`entity_id`,`attribute_id`,`value_id`,`name`,`value`,`model_id`) VALUES
        <foreach collection="item" separator="," item="item">
            (#{item.entityId},#{item.attributeId},#{item.valueId},#{item.name},#{item.value},#{item.modelId})
        </foreach>
    </insert>

使用MyBatis 原生批量插入时,当传入的LIst数据量过大就会出现以下错误

这是因为使用 MyBatis 原生批量插入拼接的插入 SQL 大小是 4.56M,而默认情况下 MySQL 可以执行的最大 SQL 为 4M,那么在程序执行时就会报错了。

解决方案:

将LIst分成多份循环插入,也就是分片批量插入

第一步:我们先要添加 Guava 框架的支持,在 pom.xml 中添加以下引用:

  <!-- google guava 工具类 -->
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0.1-jre</version>
        </dependency>

第二部:改造我们的 MyBatis 批量插入代码


  long stime = System.currentTimeMillis(); // 统计开始时间
                    System.out.println("一共插入"+bimangleDataList.size()+"条数据");
                    // 分片批量插入
                    // 分为 n 份,每份 1000 条
                    List<List<BimangleData>> listPartition = Lists.partition(bimangleDataList, 1000);
                    // 分片批量插入
                    for (List<BimangleData> item : listPartition) {
                        bimModelDataDao.saveBatch(item);
                    }
                    long etime = System.currentTimeMillis(); // 统计结束时间
                    System.out.println("执行时间:" + (etime - stime));

读取三个不同大小的模型算量测试

27152 1.7秒

72561 4秒

322830 18秒

最终结果

一次插入32w算量数据从90分钟优化成18秒

### 回答1: MyBatis批处理是一种高效的方式,可以批量插入量的数据。通用的批处理方式是使用BatchExecutor来执行批量操作,通过将多个操作添加到批处理中,然后一次性执行这些操作,可以显著提高系统的性能。 批处理模式有两种:简单批量模式和复杂批量模式。在简单批量模式下,MyBatis会将多个INSERT或UPDATE语句组合成一个批量执行语句,将它们传输给数据库一次执行。这种模式只需要配置batch="STATEMENT"即可。 在复杂批量模式下,MyBatis会将多个INSERT或UPDATE语句分别传输给数据库服务器端,然后由数据库自主组合成批量执行语句。这种模式在部分情况下比简单批量模式更加高效,但需要在配置文件中指定batch="STATEMENT"以支持预编译语句。 在实际应用中,可以通过使用ExecutorType.BATCH类型的SqlSession来实现批处理。首先创建一个包含多个操作的List,然后将它们添加到SqlSession中执行。代码如下: ```java SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); try { Mapper mapper = sqlSession.getMapper(Mapper.class); List<SomeObject> list = new ArrayList<>(); // populate the list for (SomeObject obj : list) { mapper.insert(obj); } sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); } finally { sqlSession.close(); } ``` 通过这种方式,可以轻松地实现MyBatis的通用批处理方式,幅提升系统的性能。 ### 回答2: Mybatis框架提供了通用的批处理方式,可以实现批量插入数据。具体实现步骤如下: 1. 在Mapper接口中定义一个方法,该方法采用list参数进行批量插入操作; 2. 在Mapper.xml文件中编写SQL语句,采用foreach标签进行循环插入,同时使用values标签进行数据填充,最终把SQL语句拼接成一个的SQL语句; 3. 在Java代码中调用Mapper接口中定义的批处理方法,并传入要插入的数据列表; 4. Mybatis框架会对传入的list参数进行遍历,将每个元素作为参数传入SQL语句中,最终形成一条的insert语句; 5. 使用JDBC的批处理技术将生成的SQL语句一次性提交给数据库,从而实现批量插入使用Mybatis的通用批处理方式进行数据插入,可以减少数据操作的时间和开销,提高数据处理效率。同时,这种方式也更加灵活,可以适用于各种不同的数据插入场景。 ### 回答3: MyBatis提供了一种通用的批处理方式,可以对数据进行批量插入。具体实现过程如下: 1. 在Mapper.xml中编写批量插入语句 ``` <insert id="batchInsert" parameterType="java.util.List"> insert into user(name, age, gender) values <foreach collection="list" item="user" separator=","> (#{user.name}, #{user.age}, #{user.gender}) </foreach> </insert> ``` 2. 在Java代码中调用批量插入方法 ``` public void batchInsert(List<User> userList) { sqlSessionTemplate.insert("UserMapper.batchInsert", userList); } ``` 其中,`UserMapper`是映射器的名称,`batchInsert`是Mapper.xml中insert标签的id属性值。 调用方法时,传入一个User对象的List集合即可实现批量插入。注意:在高并发情况下,批量插入会导致内存占用较高,应该采取合理的批量小。 以上就是MyBatis通用的批处理方式批量插入的实现方法。可以提高数据插入效率,减少执行时间和资源开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值