返回

高效实现MyBatis-Plus真实批量插入

后端

一. 背景

在使用 MyBatis-Plus 进行数据持久化时,可能会遇到需要批量插入大量数据的情况。默认情况下,MyBatis-Plus 提供了 insertBatch() 方法,可以实现批量插入,但该方法存在一定的问题:

  • 批量插入的数据量有限,当数据量较大时,可能会出现内存溢出等问题。
  • 批量插入时,如果其中一条数据插入失败,则整个批次的数据都将失败。

因此,为了解决这些问题,需要实现真正的批量插入,即逐条插入数据,并保证数据的一致性。

二. 解决办法

要实现真正的批量插入,可以采用以下方法:

  1. 使用 JDBC 批量插入 :通过 PreparedStatement 对象直接向数据库发送批量插入语句,可以实现更高的效率。但是,这种方法需要手动控制事务,可能会增加编码难度。
  2. 使用 MyBatis-Plus 扩展插件 :MyBatis-Plus 提供了批量插入插件,可以实现真正的批量插入,并且支持事务管理。

三. 添加依赖

使用 MyBatis-Plus 批量插入插件,需要在项目中添加以下依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-extension</artifactId>
    <version>3.5.2</version>
</dependency>

四. 继承默认方法注入

在使用 MyBatis-Plus 批量插入插件之前,需要继承默认方法注入,以便能够使用批量插入功能。在 application.yml 配置文件中,添加以下配置:

mybatis-plus:
  configuration:
    default-batch-size: 1000
    max-batch-size: 10000

其中,default-batch-size 表示默认的批量插入大小,max-batch-size 表示最大的批量插入大小。

五. 在 MyBatisPlusConfig 配置文件中注入 Bean

MyBatisPlusConfig 配置文件中,需要注入 BatchInsertAutoFillHandlerDefaultIdGenerator Bean,以便能够使用批量插入功能。添加以下配置:

@Configuration
@MapperScan("com.example.mapper")
public class MyBatisPlusConfig {

    @Bean
    public BatchInsertAutoFillHandler batchInsertAutoFillHandler() {
        return new BatchInsertAutoFillHandler();
    }

    @Bean
    public DefaultIdGenerator defaultIdGenerator() {
        return new DefaultIdGenerator();
    }
}

六. 扩展自带 BaseMapper

mapper 包下,新建一个 EasBaseMapper 接口,继承 BaseMapper 接口,并添加以下方法:

public interface EasBaseMapper<T> extends BaseMapper<T> {

    /**
     * 批量插入数据
     *
     * @param entityList 实体列表
     * @return 影响行数
     */
    int insertBatchSomeColumn(List<T> entityList);
}

在实体类中,需要添加以下注解:

@TableName("user")
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;

    private String name;

    private Integer age;

    // 省略 getter 和 setter 方法
}

service 层,调用 insertBatchSomeColumn 方法即可实现批量插入:

@Service
public class UserService {

    @Autowired
    private EasBaseMapper<User> userMapper;

    public void insertBatch() {
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            User user = new User();
            user.setName("张三" + i);
            user.setAge(20 + i);
            userList.add(user);
        }

        userMapper.insertBatchSomeColumn(userList);
    }
}

通过以上步骤,即可实现 MyBatis-Plus 的真实批量插入,提高数据库性能,简化开发工作。