背景:一般情况下,我们设计的表都会有创建人,创建时间,更新人,更新时间字段,或者是一些比较固定值的字段,如果每次新建数据或者修改数据时都手动设置上面几个通用的字段属性,就比较繁琐,我们可以通过Mybatis-Plus的MetaObjectHandler接口自动帮我们填充,不需要手动设置。
package com.example.demo.mybatisplus;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.handlers.StrictFill;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.reflection.MetaObject;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
public class CustomMetaObjectHandler implements MetaObjectHandler {
// 定义表的公共字段
private static final String CREATE_TIME_FIELD = "createTime";
private static final String CREATE_BY_FIELD = "createBy";
private static final String UPDATE_BY_FIELD = "lastUpdateBy";
private static final String UPDATE_TIME_FIELD = "lastUpdateTime";
//这里,我假如我们的表字段有year
private static final String YEAR = "year";
public CustomMetaObjectHandler() {
}
public void insertFill(MetaObject metaObject) {
//获取属性值
Object createTime = this.getFieldValByName("createTime", metaObject);
if (Objects.isNull(createTime)) {
//给createTime属性赋值
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
Object fieldValue;
Integer currentUseId;
if (metaObject.hasGetter("createBy")) {
fieldValue = this.getFieldValByName("createBy", metaObject);
if (Objects.isNull(fieldValue)) {
//从上线文对象中获取当前登录用户Id,一般情况下,用户操作时我们可以把用户登录信息存入到当前线程中,从线程本地变量中获取
currentUseId = ServiceContextHolder.getServiceContext().getUserId();
if (currentUseId == null) {
Integer defaultCreateBy = -1;
this.strictInsertFill(metaObject, "createBy", Integer.class, defaultCreateBy);
} else {
this.strictInsertFill(metaObject, "createBy", Integer.class, currentUseId);
}
}
}
if (metaObject.hasGetter("year")) {
fieldValue = this.getFieldValByName("year", metaObject);
if (Objects.isNull(fieldValue)) {
int year = new Date().getYear();
this.strictInsertFill(metaObject, "year", Integer.class, year);
}
}
}
public void updateFill(MetaObject metaObject) {
if (metaObject.hasGetter("lastUpdateBy")) {
//从上线文对象中获取当前登录用户Id,一般情况下,用户操作时我们可以把用户登录信息存入到当前线程中,从线程本地变量中获取
Integer userId = ServiceContextHolder.getServiceContext().getUserId();
if (userId == null) {
this.strictUpdateFill(metaObject, "lastUpdateBy", Integer.class, Tenant.FICTIONAL_USER_ID);
} else {
this.strictUpdateFill(metaObject, "lastUpdateBy", Integer.class, userId);
}
}
if (metaObject.hasGetter("lastModifyBy")) {
String account = ServiceContextHolder.getServiceContext().getAccount();
if (account == null || account.isEmpty()) {
this.strictUpdateFill(metaObject, "lastModifyBy", String.class, "system");
} else {
this.strictUpdateFill(metaObject, "lastModifyBy", String.class, account);
}
}
this.strictUpdateFill(metaObject, "lastUpdateTime", LocalDateTime.class, LocalDateTime.now());
}
public <T, E extends T> MetaObjectHandler strictUpdateFill(MetaObject metaObject, String fieldName, Class<T> fieldType, E fieldVal) {
return this.strictUpdateFill(this.findTableInfo(metaObject), metaObject, Collections.singletonList(StrictFill.of(fieldName, fieldType, fieldVal)));
}
public MetaObjectHandler strictUpdateFill(TableInfo tableInfo, MetaObject metaObject, List<StrictFill<?, ?>> strictFills) {
if (tableInfo.isWithUpdateFill()) {
strictFills.forEach((i) -> {
String fieldName = i.getFieldName();
Class<?> fieldType = i.getFieldType();
tableInfo.getFieldList().stream().filter((j) -> {
return j.getProperty().equals(fieldName) && fieldType.equals(j.getPropertyType()) && j.isWithUpdateFill();
}).findFirst().ifPresent((j) -> {
this.strictUpdateFillStrategy(metaObject, fieldName, i.getFieldVal());
});
});
}
return this;
}
public MetaObjectHandler strictUpdateFillStrategy(MetaObject metaObject, String fieldName, Supplier<?> fieldVal) {
Object obj = fieldVal.get();
if (Objects.nonNull(obj)) {
metaObject.setValue(fieldName, obj);
}
return this;
}
}
这样,通过自定义表公共字段的赋值逻辑,我们在往表添加记录或者更新记录时就可以只关注业务数据了