优化MyBatis-Plus批量插入策略方式

 更新时间:2026年01月14日 09:35:18   作者:快来卷java  
文章介绍了MyBatis-Plus的saveBatch方法虽然方便,但效率较低,提出了InsertBatchSomeColumn插件,可以在批量插入数据时只插入部分需要的列,从而提高效率,通过配置和代码示例,展示了如何在项目中使用该插件进行批量插入操作

一、用Mybatis-plus中的saveBatch方法

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

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 中添加以下依赖:

<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 中。
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 注解来自动生成这些方法

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 方法,用于批量插入部分列数据。

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 方法进行批量插入,并打印插入的行数。

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);
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java开发中解决Js的跨域问题过程解析

    Java开发中解决Js的跨域问题过程解析

    这篇文章主要介绍了Java开发中解决Js的跨域问题过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java加载本地库的方法之System.load与System.loadLibrary

    Java加载本地库的方法之System.load与System.loadLibrary

    最近在做的工作要用到本地方法,所以下面这篇文章主要介绍了Java加载本地库的方法之System.load与System.loadLibrary的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • 浅谈Spring Bean的基本配置

    浅谈Spring Bean的基本配置

    这篇文章主要介绍了浅谈Spring Bean的基本配置,文中有非常详细的代码示例,对正在学习java Spring的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • JavaMail实现发送邮件(QQ邮箱)

    JavaMail实现发送邮件(QQ邮箱)

    这篇文章主要为大家详细介绍了JavaMail实现发送邮件(QQ邮箱),文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • 如何使用intellij IDEA搭建Spring Boot项目

    如何使用intellij IDEA搭建Spring Boot项目

    这篇文章主要介绍了如何使用intellij IDEA搭建Spring Boot项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java 中的 switch 语句:类型支持与限制详解

    Java 中的 switch 语句:类型支持与限制详解

    Java 中的 switch 语句是一种强大的多分支选择结构,它支持多种数据类型,包括基本数据类型、字符串和枚举类型,本文给大家介绍Java 中的 switch 语句:类型支持与限制,感兴趣的朋友一起看看吧
    2024-08-08
  • Maven依赖管理之parent与dependencyManagement深入分析

    Maven依赖管理之parent与dependencyManagement深入分析

    首先我们来说说parent标签,其实这个不难解释,就是父的意思,pom也有继承的。比方说我现在有A,B,C,A是B,C的父级。现在就是有一个情况B,C其实有很多jar都是共同的,其实是可以放在父项目里面,这样,让B,C都继承A就方便管理了
    2022-10-10
  • Java实现线程通信的案例讲解

    Java实现线程通信的案例讲解

    所谓线程通信就是线程间相互发送数据,线程通信通常通过共享一个数据的方式实现。本文将通过案例详解Java中线程通信的实现,感兴趣的可以了解一下
    2022-05-05
  • java自定义日期转化类示例

    java自定义日期转化类示例

    这篇文章主要介绍了java自定义日期转化类示例,需要的朋友可以参考下
    2014-05-05
  • SpringBoot实现钉钉机器人消息推送的示例代码

    SpringBoot实现钉钉机器人消息推送的示例代码

    这篇文章主要介绍了SpringBoot实现钉钉机器人消息推送的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03

最新评论