MyBatis-Plus 自动填充功能

目录

1.前言

一般公司都会有自己的数据库相关规范,里面会包含一条建表规范,约束建表时,id、created_by、created_at、updated_by、updated_at 等一些字段是必须的,阿里巴巴Java开发规范里也提到了这点。

2.抽取基类

对于这些必须字段,一般会抽取一个基类包含这些必须字段属性,其他的实体类都继承这个基类,这样就避免了很多重复的代码。

@Data
public class BaseEntity {

    private Long id;
    private String createdBy;
    private LocalDateTime createdAt;
    private String updatedBy;
    private LocalDateTime updatedAt;

}

3.原生 MyBatis 的写法

当需要保存一个实体持久化到数据库表时,在原生 MyBatis 下的写法,需要主动通过 setter 和 getter 方法设置这些属性对应的值,这种写法在一些业务属性字段比较少的情况下,代码写起来简直难受自己。

例如,有一张订单幂等表,里面只有一个 order_id 的业务属性的字段,当我们需要插入数据时,代码的写法如下

@Test
void insert() {
    String orderId = UUID.randomUUID().toString();
    User user = UserHolder.get();
    LocalDateTime now = LocalDateTime.now();
    
    OrderIdempotent idempotent = new OrderIdempotent();
    idempotent.setOrderId(orderId);
    idempotent.setCreatedBy(user.getUsername());
    idempotent.setUpdatedBy(user.getUsername());
    idempotent.setCreatedAt(now);
    idempotent.setUpdatedAt(now);
    
    orderIdempotentMapper.insert(idempotent);
}

以上这段属性的 setter 代码,有业务价值的就 idempotent.setOrderId(orderId); 但是规范要求,又不得不手动设置更多无业务价值的字段属性。

4.MyBatis-Plus 自动填充功能

MyBatis-Plus 提供的自动填充功能,很好解决了上面问题。

首先改造基类,注解标记必填属性

@Data
public class BaseEntity {

    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField(fill = FieldFill.INSERT)
    private String createdBy;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createdAt;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updatedBy;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime updatedAt;

}

自定义实现类 MyMetaObjectHandler,在执行插入或更新实体的时候,自动将这些属性设置成对应的值

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject object) {
        User user = UserHolder.get();
        LocalDateTime now = LocalDateTime.now();
        setFieldValByName("createdBy", user.getUsername(), object);
        setFieldValByName("createdAt", now, object);
        setFieldValByName("updatedBy", user.getUsername(), object);
        setFieldValByName("updatedAt", now, object);
    }

    @Override
    public void updateFill(MetaObject object) {
        User user = UserHolder.get();
        LocalDateTime now = LocalDateTime.now();
        setFieldValByName("updatedBy", user.getUsername(), object);
        setFieldValByName("updatedAt", now, object);
    }
}
上一篇:java中的LocalDate 和LocalDateTime 基础用法


下一篇:Mybatis-Plus和mybatis共存,createtime和updatetime自动填充功能失效