优化MyBatis-Plus批量插入策略
优化MyBatis-Plus批量插入策略
一、用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);
}
}