java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > mybatis-plus 批量插入

mybatis-plus 批量插入示例代码

作者:倾听-静轩水月

正常我们使用mybatis-plus插入的时候,首先想到的是saveBatch方法,不过看了下打印出来的sql和底层代码,才发现它并不是真正的批量插入这篇文章主要介绍了mybatis-plus 批量插入示例,需要的朋友可以参考下

正常我们使用mybatis-plus插入的时候,首先想到的是saveBatch方法,不过看了下打印出来的sql和底层代码,才发现它并不是真正的批量插入。

IService 中的代码为

default boolean saveBatch(Collection<T> entityList) {
        return this.saveBatch(entityList, 1000);
    }

实现层 ServiceImpl中的代码为

public boolean saveBatch(Collection<T> entityList, int batchSize) {
        String sqlStatement = this.getSqlStatement(SqlMethod.INSERT_ONE);
        return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> {
            sqlSession.insert(sqlStatement, entity);
        });
    }

SqlMethod.INSERT_ONE 的中文枚举为

INSERT_ONE("insert", "插入一条数据(选择字段插入)", "<script>\nINSERT INTO %s %s VALUES %s\n</script>"),

通过监控控制台发现,它只是循环每1000条去插入,效率非常低。

参考网友的文章,找到一个支持批量操作的方法,下面直接贴上代码

1、添加批量操作参数类CustomSqlInjector

/**
 * 支持自定义SQL注入方法
 */
public class CustomSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        // 获取父类SQL注入方法列表
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        // 将批量插入方法添加进去
        methodList.add(new InsertBatchSomeColumn());
        return methodList;
    }
}

2、在MybatisPlusConfig中配置

@Bean
public CustomSqlInjector customSqlInjector() {
     return new CustomSqlInjector();
}

3、添加自定义 Mapper接口

/**
 * 自定义Mapper,添加批量插入接口
 * @param <T>
 */
@Mapper
public interface CustomMapper<T> extends BaseMapper<T> {
    /**
     * 批量插入
     * @param entityList 实体列表
     * @return 影响行数
     */
    Integer insertBatchSomeColumn(Collection<T> entityList);
}

4、将原来的Mapper业务接口,换成继承此接口

@Mapper
public interface StudentDao extends CustomMapper<Student> {
    List<Student> query(Student student);
}

5、再进行测试一下

@Transactional  //事务注解要加上
    @Override
    public void testBatchCreate() {
        List<Student> list = new ArrayList<>();
        int startIndex = this.lambdaQuery().select(Student::getId).count();
        for (int i = 1; i <= 1000000; i++) {
            Student student = new Student();
            Long id = SnowFlake.nextId();
            student.setId(id);
            student.setCode("studentCode-" + (startIndex + i));
            student.setName("studentName-" + (startIndex + i));
            list.add(student);
        }
        Long startTime = System.currentTimeMillis();
        System.out.println("开始批量操作:" + startTime);
        int count = this.baseMapper.insertBatchSomeColumn(list);
        Long endTime = System.currentTimeMillis();
        System.out.println("完成批量操作:" + endTime);
        System.out.println("用时:" + (endTime - startTime));
        System.out.println("保存成功:" + count);
        //this.saveBatch(list);
    }

测试结果为,1000000条数据,用时大概在 35秒左右

注意事项:

1、mysql会提示超过max_allowed_packet设置的最大值,到 my.cnf文件(windows为my.ini)修改就行了,我这直接改成 200M

2、此处为示例,实际业务中循环不要放在事务里面

到此这篇关于mybatis-plus 批量插入示例的文章就介绍到这了,更多相关mybatis-plus 批量插入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文