MyBatis-Plus(简称 MP)的Mapper 选装件是官方提供的增强扩展方法,用于弥补基础 CRUD 方法的功能短板,解决常规业务中批量操作、强制更新、逻辑删除自动填充等高频痛点。所有选装件统一存放于: com.baomidou.mybatisplus.extension.injector.methods 包下,必须配合 SQL 注入器全局注册后才能使用,无法直接调用。
这是使用所有选装件的必备前提,未配置会导致方法无法识别,抛出绑定异常。
创建配置类,注册需要使用的选装件:
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.injector.methods.AlwaysUpdateSomeColumnById;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
import com.baomidou.mybatisplus.extension.injector.methods.LogicDeleteByIdWithFill;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.SqlInjector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class MyBatisPlusConfig {
/**
* 自定义 SQL 注入器,注册选装件
*/
@Bean
public SqlInjector sqlInjector() {
return new DefaultSqlInjector() {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
// 1. 获取 MP 自带的基础方法
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
// 2. 添加需要使用的选装件(按需添加,无需全部注册)
methodList.add(new AlwaysUpdateSomeColumnById()); // 强制更新指定字段
methodList.add(new InsertBatchSomeColumn()); // 批量插入指定字段
methodList.add(new LogicDeleteByIdWithFill()); // 逻辑删除+自动填充
return methodList;
}
};
}
// 分页插件(常规配置,非选装件必需)
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}选装件不会自动注入,必须在自定义 Mapper 中手动声明方法:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface UserMapper extends BaseMapper<User> {
// 1. 强制更新指定字段(选装件)
int alwaysUpdateSomeColumnById(@Param("et") User entity);
// 2. 批量插入指定字段(选装件)
int insertBatchSomeColumn(List<User> entityList);
// 3. 逻辑删除+自动填充(选装件)
int logicDeleteByIdWithFill(@Param("et") User entity);
}方法签名:int alwaysUpdateSomeColumnById(T entity);
根据 ID 强制更新指定字段,无论字段是否为 null/ 是否修改
区别于 updateById():updateById() 会忽略 null 字段,仅更新非空字段
区别于 update():该方法强制更新注解标记的字段,适合固定字段(更新时间、版本号)
实体字段必须添加 @TableField(updateStrategy = FieldStrategy.ALWAYS) 注解:
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Long id;
private String username;
// 强制更新字段:每次调用都会更新,无论是否赋值
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private LocalDateTime updateTime;
// 版本号(强制更新场景)
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Integer version;
}每次更新数据必须刷新更新时间
乐观锁版本号强制自增
无需手动赋值,MP 自动生成更新 SQL
// 仅传入 ID,updateTime 会被强制更新
User user = new User();
user.setId(1L);
userMapper.alwaysUpdateSomeColumnById(user);方法签名:int insertBatchSomeColumn(List<T> entityList);
高性能批量插入,仅插入非空 / 指定字段
底层生成 单条 INSERT 语句(INSERT INTO table VALUES (),(),()),性能远超循环插入
只插入非 null 字段,跳过 null 字段,数据库自动使用默认值
性能提升:1000 条数据仅执行 1 次 SQL,比循环插入快 5~10 倍
灵活可控:只插入需要的字段,避免冗余数据
大批量数据导入(Excel 导入、批量注册用户)
仅插入部分字段,保留数据库默认值
List<User> userList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
User user = new User();
user.setUsername("test" + i);
// 不设置 id(数据库自增)、不设置 createTime(自动填充)
userList.add(user);
}
// 批量插入,仅插入 username 等非空字段
userMapper.insertBatchSomeColumn(userList);方法签名:int logicDeleteByIdWithFill(T entity);
逻辑删除 + 自动填充删除字段
逻辑删除:不物理删除数据,通过 deleted 字段标记为已删除
自动填充:删除时自动填充 deleteTime、deleteUser 等字段
实体类配置逻辑删除注解 + 自动填充
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Long id;
// 逻辑删除字段:0-未删除,1-已删除
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
// 删除时间(自动填充)
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime deleteTime;
// 删除人(自动填充)
@TableField(fill = FieldFill.UPDATE)
private String deleteUser;
}配置自动填充处理器
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入时填充
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "deleted", Integer.class, 0);
}
// 逻辑删除时填充
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "deleteTime", LocalDateTime.class, LocalDateTime.now());
this.strictUpdateFill(metaObject, "deleteUser", String.class, "系统管理员");
}
}业务要求数据不可物理删除,仅标记删除
删除时需要记录删除时间、操作人
User user = new User();
user.setId(1L);
// 逻辑删除,自动填充 deleteTime、deleteUser
userMapper.logicDeleteByIdWithFill(user);