优化MyBatis-Plus批量插入策略

优化MyBatis-Plus批量插入策略

优化MyBatis-Plus批量插入策略

一、用Mybatis-plus中的saveBatch方法

MyBatis-Plus 的 Service 层提供了 saveBatch 方法,可以方便地实现批量插入操作。但查阅源码发现,saveBatch的底层还是逐条插入的,这就会导致当数据量大的时候程序运行效率变慢

java 复制代码
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;

// 假设实体类为 User
class User {
    private Long id;
    private String name;

    // 构造函数、getter 和 setter 方法
    public User() {}

    public User(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

// 假设 UserMapper 继承自 BaseMapper
interface UserMapper extends com.baomidou.mybatisplus.core.mapper.BaseMapper<User> {}

// UserService 继承自 ServiceImpl
@Service
class UserService extends ServiceImpl<UserMapper, User> {
    public boolean saveUserBatch(List<User> userList) {
        return this.saveBatch(userList);
    }
}

// 调用示例
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService();
        java.util.List<User> userList = new java.util.ArrayList<>();
        userList.add(new User(1L, "Alice"));
        userList.add(new User(2L, "Bob"));

        boolean result = userService.saveUserBatch(userList);
        if (result) {
            System.out.println("批量插入成功");
        } else {
            System.out.println("批量插入失败");
        }
    }
}

二、InsertBatchSomeColumn插件

它继承了Abstractmethod类,在 MyBatis-Plus 中,InsertBatchSomeColumn 是一种用于批量插入部分列数据的插入策略,它可以帮助我们在批量插入数据时只插入部分需要的列,而不是插入所有列。

1.使用前配置

首先,确保你的项目中已经添加了 MyBatis-Plus 和 MySQL 驱动的依赖。如果你使用的是 Maven 项目,可以在 pom.xml 中添加以下依赖:

java 复制代码
<dependencies>
    <!-- MyBatis-Plus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <!-- MySQL 驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.32</version>
    </dependency>
</dependencies>

2.代码示例

1.配置类 MybatisPlusConfig
  • 创建一个自定义的 DefaultSqlInjector,并在 getMethodList 方法中添加 InsertBatchSomeColumn 方法,将其注入到 MyBatis-Plus 中。
java 复制代码
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class MybatisPlusConfig {
    @Bean
    public DefaultSqlInjector sqlInjector() {
        return new DefaultSqlInjector() {
            @Override
            public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
                List<AbstractMethod> methodList = super.getMethodList(mapperClass);
                methodList.add(new InsertBatchSomeColumn());
                return methodList;
            }
        };
    }
}    
2).实体类 User

使用 @TableName 注解指定该实体类对应的数据库表名。

为每个属性提供了对应的 getter 和 setter 方法,这里使用了 Lombok 的 @Data 注解来自动生成这些方法

java 复制代码
ximport com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("user")
public class User {
    private Long id;
    private String name;
    @TableField("age")
    private Integer age;
    private String email;
}    
3).Mapper 接口 UserMapper

继承自 BaseMapper,继承了 MyBatis-Plus 提供的基本 CRUD 方法。

使用 @InsertProvider 注解指定插入方法的 SQL 提供者为 InsertBatchSomeColumn,并调用其 sql 方法生成 SQL 语句。

定义了 insertBatchSomeColumn 方法,用于批量插入部分列数据。

java 复制代码
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import com.baomidou.mybatisplus.extension.plugins.inner.SqlParserInner;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.builder.annotation.ProviderMethodResolver;

import java.util.List;

public interface UserMapper extends BaseMapper<User>, ProviderMethodResolver {
    @InsertProvider(type = InsertBatchSomeColumn.class, method = "sql")
    int insertBatchSomeColumn(@Param("list") List<User> list);
}    
4).测试类 InsertBatchTest

实现 CommandLineRunner 接口,在 run 方法中进行测试。

创建多个 User 对象并添加到列表中。

调用 UserMapper 的 insertBatchSomeColumn 方法进行批量插入,并打印插入的行数。

jaVA 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

@SpringBootApplication
public class InsertBatchTest implements CommandLineRunner {

    @Autowired
    private UserMapper userMapper;

    public static void main(String[] args) {
        SpringApplication.run(InsertBatchTest.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        List<User> userList = new ArrayList<>();
        User user1 = new User();
        user1.setName("Alice");
        user1.setAge(20);
        userList.add(user1);

        User user2 = new User();
        user2.setName("Bob");
        user2.setAge(22);
        userList.add(user2);

        int rows = userMapper.insertBatchSomeColumn(userList);
        System.out.println("插入行数: " + rows);
    }
}    
复制代码
    user2.setName("Bob");
    user2.setAge(22);
    userList.add(user2);

    int rows = userMapper.insertBatchSomeColumn(userList);
    System.out.println("插入行数: " + rows);
}

}

复制代码
相关推荐
面朝大海,春不暖,花不开16 分钟前
自定义Spring Boot Starter的全面指南
java·spring boot·后端
得过且过的勇者y17 分钟前
Java安全点safepoint
java
夜晚回家1 小时前
「Java基本语法」代码格式与注释规范
java·开发语言
斯普信云原生组1 小时前
Docker构建自定义的镜像
java·spring cloud·docker
wangjinjin1801 小时前
使用 IntelliJ IDEA 安装通义灵码(TONGYI Lingma)插件,进行后端 Java Spring Boot 项目的用户用例生成及常见问题处理
java·spring boot·intellij-idea
wtg44521 小时前
使用 Rest-Assured 和 TestNG 进行购物车功能的 API 自动化测试
java
白宇横流学长2 小时前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
fat house cat_2 小时前
【redis】线程IO模型
java·redis
stein_java3 小时前
springMVC-10验证及国际化
java·spring
weixin_478689763 小时前
C++ 对 C 的兼容性
java·c语言·c++