MyBatis-Plus 自动填充的实现示例
作者:Flying_Fish_Xuan
在日常开发中,数据库表通常会包含一些系统自动维护的字段,例如:创建时间、更新时间、操作人等。为了减少手动维护这些字段的重复代码,MyBatis-Plus 提供了自动填充功能,帮助开发者在插入或更新数据时,自动为某些字段赋值。
1. MyBatis-Plus 自动填充简介
MyBatis-Plus 提供的自动填充功能,可以在数据库插入或更新时,自动为指定的字段设置值,而不需要每次手动传递。例如:
- 在记录插入时自动填充创建时间
created_at。 - 在记录更新时自动填充更新时间
updated_at。 - 自动填充操作用户 ID 或者一些其他固定值。
MyBatis-Plus 通过 @TableField 注解中的 fill 属性和 MetaObjectHandler 接口来实现自动填充。fill 属性用于指定字段在插入或更新时是否自动填充,而 MetaObjectHandler 是用于实现自动填充逻辑的接口。
2. 自动填充的配置步骤
2.1 在实体类中标注需要自动填充的字段
MyBatis-Plus 通过 @TableField(fill = ...) 注解来标注需要自动填充的字段,并指定该字段的填充策略。常见的填充策略有:
FieldFill.INSERT:在插入时自动填充。FieldFill.UPDATE:在更新时自动填充。FieldFill.INSERT_UPDATE:在插入和更新时都自动填充。
示例:
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Integer id;
private String username;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createdAt; // 插入时自动填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedAt; // 插入和更新时自动填充
}
createdAt:在插入记录时自动填充当前时间。updatedAt:在插入和更新记录时自动填充当前时间。
2.2 创建自动填充处理器
MyBatis-Plus 提供了 MetaObjectHandler 接口,开发者可以实现该接口中的 insertFill 和 updateFill 方法来自定义填充逻辑。
示例:
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, "createdAt", LocalDateTime::now, LocalDateTime.class); // 创建时间
this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class); // 更新时间
}
// 更新时自动填充
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class); // 更新时间
}
}
strictInsertFill:用于在插入操作时自动填充指定字段。strictUpdateFill:用于在更新操作时自动填充指定字段。
在 insertFill 方法中,createdAt 和 updatedAt 字段会在插入时自动填充当前时间。而在 updateFill 方法中,updatedAt 字段会在更新时自动填充当前时间。
2.3 完整示例
以下是一个完整的 MyBatis-Plus 自动填充示例,包含实体类、填充处理器和测试代码:
1. User 实体类
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.IdType;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createdAt; // 创建时自动填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedAt; // 创建和更新时自动填充
}
2. 自动填充处理器
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, "createdAt", LocalDateTime::now, LocalDateTime.class);
this.strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
}
}
3. UserMapper 接口
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
4. 测试代码
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyTestRunner implements CommandLineRunner {
@Autowired
private UserMapper userMapper;
@Override
public void run(String... args) throws Exception {
// 测试插入时自动填充
User user = new User();
user.setUsername("John Doe");
userMapper.insert(user);
System.out.println("Inserted user: " + user);
// 测试更新时自动填充
user.setUsername("Jane Doe");
userMapper.updateById(user);
System.out.println("Updated user: " + user);
}
}
在上面的测试代码中:
- 插入新用户时,
createdAt和updatedAt字段都会被自动填充。 - 更新用户时,
updatedAt字段会被自动更新。
3. 自动填充策略详解
3.1 自动填充策略选项
@TableField 注解的 fill 属性支持以下自动填充策略:
FieldFill.INSERT:仅在插入时自动填充。FieldFill.UPDATE:仅在更新时自动填充。FieldFill.INSERT_UPDATE:在插入和更新时都自动填充。
@TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updatedAt;
3.2 MetaObjectHandler 方法详解
strictInsertFill:用于插入时自动填充字段,接受 4 个参数:MetaObject、字段名、填充值和字段类型。
this.strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);
strictUpdateFill:用于更新时自动填充字段。
this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
如果不需要区分插入和更新,可以直接使用 setFieldValByName 方法:
this.setFieldValByName("updatedAt", LocalDateTime.now(), metaObject);
3.3 手动触发填充
在某些场景下,可能希望在代码中手动触发自动填充逻辑,可以使用 fillStrategy 方法。
MetaObject metaObject = SystemMetaObject.forObject(user); this.fillStrategy(metaObject, "updatedAt", LocalDateTime.now());
4. 自动填充的注意事项
4.1 数据库默认值冲突
如果数据库字段设置了默认值,且实体类同时使用了自动填充,可能会导致冲突。解决办法是在数据库中移除默认值,完全依赖 MyBatis-Plus 进行自动填充。
4.2 MetaObjectHandler 必须注册为 Spring Bean
自动填充处理器类 MetaObjectHandler 必须由 Spring 容器管理(即使用 @Component 注解),否则自动填充不会生效。
4.3 覆盖已有值
在插入或更新时,MyBatis-Plus 会自动为标注了 fill 的字段赋值,但如果这些字段已经有值,则 MyBatis-Plus 默认不会覆盖已有值
。要覆盖已有值,可以使用 strictInsertFill 或 strictUpdateFill。
5. 常见使用场景
5.1 创建时间和更新时间自动填充
在大多数数据库表中,都会有 created_at 和 updated_at 字段,用于记录数据的创建时间和最后更新时间。通过自动填充功能,MyBatis-Plus 可以轻松实现这两个字段的自动维护。
5.2 操作人自动填充
在操作日志、审计系统等场景下,通常需要记录操作人 ID。可以通过自动填充机制,在插入和更新记录时,自动获取当前用户 ID 并填充到表中。
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "operatorId", () -> getCurrentUserId(), Long.class);
}
6. 总结
MyBatis-Plus 的自动填充功能能够极大地简化开发工作,通过简单的注解和配置即可实现插入、更新时的字段自动填充,减少了手动维护重复字段的代码量。
@TableField(fill = ...):用于指定字段的自动填充策略,支持插入、更新和插入更新。MetaObjectHandler:自定义自动填充逻辑的接口,开发者可以通过实现insertFill和updateFill方法控制填充行为。
到此这篇关于MyBatis-Plus 自动填充的实现示例的文章就介绍到这了,更多相关MyBatis-Plus 自动填充内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
