MyBatis-Plus 实现自动填充和逻辑删除

Spring Boot & MyBatis-Plus 实现自动填充和逻辑删除
业务需求
前台显示创建人、创建时间、修改人、修改时间,并记录删除人和删除时间。为了方便数据恢复和保护数据本身价值,希望删除后能找回记录。
相关原理
自动填充原理
关键是在实体类需要自动填充的字段中声明 @TableField 注解的 fill 属性,以及实现元对象处理器接口 MetaObjectHandler。
- 填充原理是直接给
entity的属性设置值 - 注解则是指定该属性在对应情况下必有值,如果无值则入库会是
null MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充- 字段必须声明
TableField注解,属性fill选择对应策略(见附录),该声明告知Mybatis-Plus需要预留注入SQL字段 - 填充处理器
MyMetaObjectHandler在 Spring Boot 中需要声明@Component或@Bean注入
附录:
|
|
逻辑删除原理
简而言之,逻辑删除就是将 delete 替换为 update 操作。
只对自动注入的 SQL 起效(不支持自定义 SQL):
- 插入: 不作限制
- 查找:追加 where 条件过滤掉已删除数据,且使用条件构造器
wrapper.entity生成的 where 条件会忽略该字段 - 更新:追加where条件防止更新到已删除数据,且使用条件构造器
wrapper.entity生成的 where 条件会忽略该字段 - 删除:转变为 更新
字段类型支持说明:
- 支持所有数据类型(推荐使用
Integer,Boolean,LocalDateTime) - 如果数据库字段使用
datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()
具体实现
步骤一:数据库设计
向相关表中添加以下字段:
| 字段 | 类型 | 注释 |
|---|---|---|
| create_user | bigint | 创建人id |
| create_time | datetime | 创建时间 |
| update_user | bigint | 修改人id |
| update_time | datetime | 修改时间 |
| delete_user | bigint | 删除人id |
| delete_time | datetime | 删除时间 |
| is_deleted | bit(1) | 是否删除(默认值0) |
步骤二:逻辑删除配置
在 Spring Boot 配置文件 application.yml 或者 application.properties 中配置逻辑删除配置。
以 application.yml 为例:
|
|
以上操作与 @TableLogic(value = "0", delval = "1") 添加注解属性同理,未删除状态值 value 默认为 0,已删除状态值 delval 默认为1。
步骤三:修改实体类
在需要实现自动填充和逻辑删除的相关实体类中添加以下字段及注解:
|
|
以上代码中有几点需要注意:
- 由于
创建人和创建时间是添加(插入)操作时自动填充,所以fill属性为FieldFill.INSERT - 同理,
修改人和修改时间是在修改操作时自动填充,所以fill属性为FieldFill.UPDATE - MyBatis-Plus 官方并未提供删除操作的自动填充方法,所以不需要在
删除人和删除时间字段定义fill属性。不能用FieldFill.UPDATE或其他属性代替,否则在修改操作的时候也会更新该字段的值(具体实现见下文) - 在需要标识为”是否删除”的字段加上
@TableLogic注解,如果数据库中没有定义默认值,可以在此处设置isDeleted = false
步骤四:实现自动填充
自定义一个类 CustomMetaObjectHandler 实现 MetaObjectHandler 接口:
|
|
注:以上写法在 MyBatis-Plus 3.3.0 以上版本 有效。
此时还剩余 删除人 和 删除时间 没有设置自动填充,由于 MyBatis-Plus 官方没有给出具体实现,可以使用下述方法:
在 Service 类的删除实现方法中,分别设置删除人 id 和删除时间,并作 updateById 操作,可以同时实现自动填充和逻辑删除。
|
|
总结
MyBatis-Plus 自带的接口和配置让自动填充和逻辑删除的实现更加简单,仅需添加 @TableField 注解的 fill 属性和添加 @TableLogic 注解即可实现这两个功能,通过实现 MetaObjectHandler 接口可个性化地定义填充内容和逻辑。
另外需要说明:
- 创建人、修改人、删除人字段可以用字符串代替,显示更直观,减少后端根据用户 id 查询用户名的压力,但为了区分可能出现的同名情况,保留 id 更为合适(需要根据实际衡量)
- MyBatis-Plus 3.3.0 以下的版本可以使用
setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject, FieldFill fieldFill)方法设置填充值