mybatis批量插入10万条数据的优化过程


数据库 在使用mybatis插入大量数据的时候,为了提高效率,放弃循环插入,改为批量插入,mapper如下:
package com.lcy.service.mapper;

import com.lcy.service.pojo.TestVO;
import org.apache.ibatis.annotations.Insert;

import java.util.List;

public interface TestMapper {

    @Insert("")
    Integer testBatchInsert(List list);

}

实体类:

package com.lcy.service.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestVO {

    private String t1;

    private String t2;

    private String t3;

    private String t4;

    private String t5;

}

测试类如下:

import com.lcy.service.TestApplication;
import com.lcy.service.mapper.TestMapper;
import com.lcy.service.pojo.TestVO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest(classes = TestApplication.class)
@RunWith(SpringRunner.class)
public class TestDemo {

    @Autowired
    private TestMapper testMapper;

    @Test
    public void insert() {
        List list = new ArrayList<>();
        for (int i = 0; i < 200000; i++) {
            list.add(new TestVO(i + "," + i, i + "," + i, i + "," + i, i + "," + i, i + "," + i));
        }
        System.out.println(testMapper.testBatchInsert(list));
    }

}

为了复现bug,我限制了JVM内存:

执行测试类报错如下:

java.lang.OutOfMemoryError: Java heap space

	at java.base/java.util.Arrays.copyOf(Arrays.java:3746)

可以看到,Arrays在申请内存的时候,导致栈内存溢出
改进方法,分批新增:

import com.lcy.service.TestApplication;
import com.lcy.service.mapper.TestMapper;
import com.lcy.service.pojo.TestVO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@SpringBootTest(classes = TestApplication.class)
@RunWith(SpringRunner.class)
public class TestDemo {

    @Autowired
    private TestMapper testMapper;

    @Test
    public void insert() {
        List list = new ArrayList<>();
        for (int i = 0; i < 200000; i++) {
            list.add(new TestVO(i + "," + i, i + "," + i, i + "," + i, i + "," + i, i + "," + i));
        }
        int index = list.size() / 10000;
        for (int i=0;i< index;i++){
            //stream流表达式,skip表示跳过前i*10000条记录,limit表示读取当前流的前10000条记录
            testMapper.testBatchInsert(list.stream().skip(i*10000).limit(10000).collect(Collectors.toList()));
        }
    }

}

还有一种方法是调高JVM内存,不过不建议使用,不仅吃内存,而且数据量过大会导致sql过长报错


注 文章链接参考 https://www.it610.com/article/1298060170571620352.htm 本文章做个人学习记录如有侵权联系本人删除
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
可以使用Oracle的批量更新功能和MyBatis来实现批量更新几万条数据。 首先,你需要在MyBatis的映射文件中编写一个更新语句,例如: ```xml <update id="batchUpdate" parameterType="java.util.List"> <!-- 这里是你的更新语句,使用动态SQL来处理批量更新 --> UPDATE your_table SET column1 = #{listItem.value1}, column2 = #{listItem.value2} WHERE id = #{listItem.id} </update> ``` 然后,在Java代码中,你可以使用MyBatis的`SqlSession`对象来批量执行该更新语句。你需要将要更新的数据封装到一个List中,然后调用`update`方法来执行批量更新,示例如下: ```java List<YourEntity> dataList = new ArrayList<>(); // 要更新的数据列表 for (int i = 0; i < dataSize; i++) { YourEntity entity = new YourEntity(); // 设置要更新的字段值 entity.setId(idList.get(i)); entity.setValue1(value1List.get(i)); entity.setValue2(value2List.get(i)); dataList.add(entity); } try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { // 批量更新 int batchSize = 1000; // 每批次更新的数据量 int totalSize = dataList.size(); int batchCount = totalSize / batchSize + (totalSize % batchSize == 0 ? 0 : 1); for (int i = 0; i < batchCount; i++) { int fromIndex = i * batchSize; int toIndex = Math.min((i + 1) * batchSize, totalSize); List<YourEntity> batchList = dataList.subList(fromIndex, toIndex); sqlSession.update("yourMapper.batchUpdate", batchList); sqlSession.commit(); // 提交事务 sqlSession.clearCache(); // 清理缓存 } } ``` 这样就实现了批量更新几万条数据的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值