在日常开发中,我们经常需要为实体类的某些字段(如创建时间、逻辑删除标记)设置默认值。如果每次操作都手动赋值,不仅繁琐还容易遗漏。MyBatis-Plus 提供的自动填充功能完美解决了这个问题。
一、自动填充是什么?为什么需要它?
自动填充是 MyBatis-Plus 提供的字段自动赋值机制,核心作用是:在执行插入(INSERT)或更新(UPDATE)操作时,根据预设规则自动为指定字段赋值,无需手动调用 setXxx() 方法。
常见应用场景:
- 逻辑删除标记(deleted):插入时默认值为 0(未删除)
- 创建时间(createTime):插入时自动填充当前时间
- 更新时间(updateTime):插入和更新时均填充当前时间
使用自动填充能减少重复代码,避免人为疏忽导致的字段值错误,提高开发效率。
二、实现自动填充的核心步骤
实现自动填充需要两步:标记需要填充的字段 和 定义填充规则。下面以逻辑删除字段 deleted 为例,详解具体实现。
步骤 1:在实体类中标记自动填充字段
通过 @TableField 注解指定字段的填充策略(何时需要自动填充):
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
@Data
public class Student {
// 主键
@TableId(type = IdType.AUTO)
private Long id;
// 学生姓名
private String name;
// 逻辑删除标记(0-未删除,1-已删除)
@TableLogic // 标记为逻辑删除字段(非必需,视业务而定)
@TableField(fill = FieldFill.INSERT) // 插入时自动填充
private Integer deleted;
}
注解说明:
- @TableField(fill = FieldFill.INSERT):核心注解,fill 属性指定填充时机:
- FieldFill.DEFAULT:默认不填充(默认值)
- FieldFill.INSERT:仅插入时填充
- FieldFill.UPDATE:仅更新时填充
- FieldFill.INSERT_UPDATE:插入和更新时均填充
- @TableLogic:可选注解,用于标记逻辑删除字段(与自动填充配合使用,实现逻辑删除功能)。
步骤 2:自定义填充规则(实现 MetaObjectHandler 接口)
创建一个类实现 MetaObjectHandler 接口,并重写插入和更新的填充方法,定义具体填充值:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
// 交给 Spring 管理,让 MyBatis-Plus 能扫描到
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入操作时的填充逻辑
*/
@Override
public void insertFill(MetaObject metaObject) {
// 为字段名 "deleted" 填充值 0
// 参数1:字段名(需与实体类属性名一致)
// 参数2:填充值
// 参数3:元对象(固定参数)
this.setFieldValByName("deleted", 0, metaObject);
// 扩展:插入时自动填充创建时间
// this.setFieldValByName("createTime", new Date(), metaObject);
}
/**
* 更新操作时的填充逻辑(本例暂不实现)
*/
@Override
public void updateFill(MetaObject metaObject) {
// 示例:更新时自动填充更新时间
// this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
关键说明:
- 类上必须添加 @Component 注解,否则 MyBatis-Plus 无法识别该填充规则。
- insertFill 方法:定义插入时的填充值,本例中为 deleted 字段填充 0(未删除)。
- updateFill 方法:定义更新时的填充值,可根据业务需求添加逻辑(如自动更新时间)。
步骤 3:测试自动填充效果
编写测试代码,执行插入操作,验证 deleted 字段是否自动填充:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.example.mapper.StudentMapper;
import com.example.entity.Student;
@SpringBootTest
public class StudentTest {
@Autowired
private StudentMapper studentMapper;
@Test
public void testInsert() {
// 创建学生对象,不手动设置 deleted 字段
Student student = new Student();
student.setName("张三"); // 仅设置姓名
// 执行插入操作
int rows = studentMapper.insert(student);
System.out.println("插入成功,影响行数:" + rows);
}
}
测试结果:
查看数据库会发现,新插入的记录中 deleted 字段值为 0,说明自动填充生效——即使没有手动调用 student.setDeleted(0),程序也会按预设规则赋值。
三、扩展场景:自动填充时间字段
除了逻辑删除标记,自动填充最常用的场景是时间字段(创建时间、更新时间)。实现方式如下:
1. 实体类添加时间字段并标记填充策略
@Data
public class Student {
// 其他字段…
@TableField(fill = FieldFill.INSERT) // 仅插入时填充
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时均填充
private LocalDateTime updateTime;
}
2. 在填充类中添加时间填充逻辑
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 填充删除标记
this.setFieldValByName("deleted", 0, metaObject);
// 填充创建时间(当前时间)
this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
// 插入时同时填充更新时间
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
// 更新时填充更新时间(当前时间)
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
此时,执行插入或更新操作时,createTime 和 updateTime 会自动填充为当前时间,无需手动设置。
总结
MyBatis-Plus 的自动填充功能通过 @TableField 注解标记字段 和 MetaObjectHandler 实现类定义规则,实现了字段的自动赋值,极大简化了重复代码。无论是逻辑删除标记、时间字段还是其他需要默认值的场景,都能通过这一机制高效处理。
评论前必须登录!
注册