关于mybais-plus自动设置创建时间等

//这是公共父类包含创建时间,创建人等信息
@JsonIgnoreProperties({"transMap"})
public abstract class BaseDO implements Serializable, TransPojo {
    @TableField(
        fill = FieldFill.INSERT//核心表示该字段是在添加时设置
    )
    private LocalDateTime createTime;
    @TableField(
        fill = FieldFill.INSERT_UPDATE//表示该字段在添加更新时设置
    )
    private LocalDateTime updateTime;
    @TableField(
        fill = FieldFill.INSERT//表示字段在添加时设置
    )
    private String creator;
    @TableField(
        fill = FieldFill.INSERT_UPDATE,//表示该字段在添加更新时设置
    )
    private String updater;
    @TableLogic
    private Boolean deleted;
}

//这是实体类继承了BaseDO当然该实体类对应的数据表有创建时间这些字段
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MaterialCategoryDO extends BaseDO {

    /**
     * 主键ID
     */
    @TableId(type = IdType.ASSIGN_ID)
    private Long materialCategoryId;
    /**
     * 物品分类ID
     */
    private Long parentId;
    /**
     * 物品分类名称
     */
     */
}
materialCategoryMapper.insert(materialCategory);//service层直接调用就行

除此之外还要写个拦截器,通过拦截器拦截并设置创建时间等字段

这里并没有写@Component注解注入到 Spring 容器,因为在其他地方配置过了

@Configuration
public class MybatisPlusConfig {
    // 手动注册处理器
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new DefaultDBFieldHandler();
    }
}
public class DefaultDBFieldHandler implements MetaObjectHandler {//这里需要继承这个接口原因后面会讲

    @Override
    public void insertFill(MetaObject metaObject) {
        if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseDO) {
            BaseDO baseDO = (BaseDO) metaObject.getOriginalObject();

            Date current = new Date();
            // 创建时间为空,则以当前时间为插入时间
            if (Objects.isNull(baseDO.getCreateTime())) {
                baseDO.setCreateTime(current);
            }
            // 更新时间为空,则以当前时间为更新时间
            if (Objects.isNull(baseDO.getUpdateTime())) {
                baseDO.setUpdateTime(current);
            }
            
            String userId = ..... 这里自定义实现逻辑,获取当前登录用户
            
            // 当前登录用户不为空,创建人为空,则当前登录用户为创建人
            if (Objects.nonNull(userId) && Objects.isNull(baseDO.getCreator())) {
                baseDO.setCreator(userId.toString());
            }
            // 当前登录用户不为空,更新人为空,则当前登录用户为更新人
            if (Objects.nonNull(userId) && Objects.isNull(baseDO.getUpdater())) {
                baseDO.setUpdater(userId.toString());
            }
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 更新时间为空,则以当前时间为更新时间
        Object modifyTime = getFieldValByName("updateTime", metaObject);
        if (Objects.isNull(modifyTime)) {
            setFieldValByName("updateTime", new Date(), metaObject);
        }

        // 当前登录用户不为空,更新人为空,则当前登录用户为更新人
        Object modifier = getFieldValByName("updater", metaObject);
        
        String userId = ..... 这里自定义实现逻辑,获取当前登录用户
        
        if (Objects.nonNull(userId) && Objects.isNull(modifier)) {
            setFieldValByName("updater", userId.toString(), metaObject);
        }
    }
}

核心就是mybatis-plus能够自动检测@TableField(fill=...)注解,然后通过拦截器来设置创建时间等字段

具体的调用过程图如下

可以看到这里的BaseDO声明为抽象类

  • 设计意图BaseDO 仅作为基础模板存在,包含所有实体共有的审计字段

  • 强制约束:要求开发者必须创建具体子类(如 MaterialCategoryDO)才能使用

  • 类比现实:类似"动物"抽象类,必须通过"猫"/"狗"等具体子类实例化

注意到这里继承了MetaObjectHandler

因为 MyBatis Plus 通过接口类型识别处理器所以需要继承这个接口

核心代码

// MyBatis Plus 的填充处理器接口
public interface MetaObjectHandler {
    void insertFill(MetaObject metaObject);  // 插入操作时触发
    void updateFill(MetaObject metaObject);  // 更新操作时触发
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值