1.自动填充接口MetaObjectHandler
1.1简介
MetaObjectHandler 是 MyBatis-Plus 提供的一个接口,它允许开发者自定义一些逻辑来处理 MyBatis 操作中的元数据,比如自动填充字段。这个接口提供了几个方法,可以在 MyBatis 执行插入(insert)和更新(update)操作时自动填充字段值。
以下是 MetaObjectHandler 接口中定义的方法:
- insertFill(MetaObject metaObject): 在插入操作之前调用,用于填充插入时需要的字段。
- updateFill(MetaObject metaObject): 在更新操作之前调用,用于填充更新时需要的字段。
1.2场景
使用 MetaObjectHandler 的典型场景包括自动设置创建时间、更新时间、当前创建人、当前更新人等字段,这些字段通常不需要用户手动设置,而是在数据操作时自动生成。
1.3使用方法
①定义实体表如产品表ProductInfo(@Schema是接口文档生成注解可以忽略)
在逻辑删除、创建人、修改人、创建时间、修改时间字段使用字段自动填充,当我们操作数据库进行insert和update操作这些字段会自动填充数据。
@Data
@TableName(value = "product_info")
public class ProductInfo implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "课程id")
private Integer courseId;
@Schema(description = "商品名字")
private String productName;
@Schema(description = "商品描述")
private String description;
@Schema(description = "逻辑删除描述 0 正常 1 删除")
@TableField(fill = FieldFill.INSERT)
private Integer delFlag;
@Schema(description = "创建用户")
@TableField(fill = FieldFill.INSERT)
private Integer createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
@Schema(description = "修改用户")
private Integer updateUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
@Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "修改时间")
private Date updateTime;
}
以下是 @FieldFill 注解的几个选项:
- DEFAULT: 默认填充策略。在插入操作时,只填充不为 NULL 的字段;在更新操作时,只填充字段值不为 NULL 或者字段值被修改的字段。
- INSERT: 仅在插入时填充字段。
- UPDATE: 仅在更新时填充字段。
- INSERT_UPDATE: 插入和更新时都填充字段。
②Mapper上使用@Mapper注解继承BaseMapper
*/
@Mapper
public interface EduProductInfoMapper extends BaseMapper<EduProductInfo> {
}
③定义处理器实现MetaObjectHandler接口
定义配置类加上@Component注解加入spring容器管理,实现MetaObjectHandler接口重写insertFill和updateFill方法表示插入和更新时候进行的操作。
- 如下面this.setFieldValByName(“createTime”, new Date(), metaObject);表示插入操作时插入new Date()当前时间
- 如this.setFieldValByName(“delFlag”,0,metaObject);表示逻辑删除字段设置默认0
- FCtx.getId()是我自己定义的方法,利用使用ThreadLocal获取用户id
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("createUser",FCtx.getId() , metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("updateBy", FCtx.getId(), metaObject);
this.setFieldValByName("delFlag",0,metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("updateUser", FCtx.getId(), metaObject);
}
}
1.4注意事项
1.4.1 使用MybatisPlus语法insert插入和update更新操作一定要是对实体类操作,如上面产品表ProductInfo,填充原理是直接给entity的属性设置值!!!
Insert(ProductInfo)或者update(ProductInfo)
这种情况不会进行属性填充,mybatisPlus指定字段更新,其他字段不会更新
UpdateWrapper<ProductInfo> Wrapper = new UpdateWrapper<>();
Wrapper.eq("id", 30).set("productName", "乐事薯片");
ProductInfoService.update(null, Wrapper);
注解则是指定该属性在对应情况下必有值,如果无值则入库会是null
MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充。
1.4.2 使用Mapper.xml中,填充数据是在执行完自定义的sql之后填充的数据,所以在写sql语句的时候,需要自动填充的字段不可以使用非空判断。
如我上图定义的createTime自动插入
不能使用!
<if test="createTime !=null">createTime,</if>
2.逻辑删除字段
2.1简介
逻辑删除是一种用于表示数据删除状态的数据处理方式。在逻辑删除中,数据并没有从数据库中真正被删除,而是通过标记或更新一个字段来表示该数据已被删除。
如上面我定义ProductInfo表delFlag为逻辑删除字段,以设置自动填充属性插入为0 当我执行删除操作,将他自动设置成1.
@Schema(description = "逻辑删除描述 0 正常 1 删除")
@TableField(fill = FieldFill.INSERT)
private Integer delFlag;
逻辑删除的好处是可以保留数据的历史记录,以便在需要时进行恢复或审计。同时,它还可以避免由于误操作或数据完整性问题导致的数据丢失。
需要注意的是,逻辑删除只是一种数据处理方式,并不代表数据真正被删除。在实际应用中,需要根据具体情况选择合适的数据处理方式,并确保数据的安全性和完整性。
2.2使用
# mybatis-plus相关配置
mybatis-plus:
# 全局配置
global-config:
db-config:
# 全局逻辑删除的字段名
logic-delete-field: delFlag
# 逻辑已删除值(默认为 1)
logic-delete-value: 1
# 逻辑未删除值(默认为 0)
logic-not-delete-value: 0
id-type: auto