目录
版本:3.5.2
一、为什么需要用到公共字段自动填充:
二、代码实现:
这里的框架指的是mybatisPlus框架。
步骤一:
推荐存放位置:
实现该接口MetaObjectHandler(元数据对象处理器):
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入操作,自动填充
* @param metaObject 元对象
*/
@Override
public void insertFill(MetaObject metaObject) {
//自动填充时间
this.strictInsertFill(metaObject,"createTime", LocalDateTime.class,LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
//自动填充用户id
this.strictInsertFill(metaObject,"createUser", Long.class,BaseContext.getCurrentId());
this.strictInsertFill(metaObject,"updateUser", Long.class,BaseContext.getCurrentId());
this.strictInsertFill(metaObject,"isDeleted", Integer.class,0);
}
/**
* 更新操作,自动填充
* @param metaObject 元对象
*/
@Override
public void updateFill(MetaObject metaObject) {
//针对updateById方法导致自动填充失效,用setFieldValByName方法
// this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
//自动填充用户id
this.setFieldValByName("updateUser", BaseContext.getCurrentId(),metaObject);
}
}
步骤二:
/**
*员工实体
*/
@Data
public class Employee {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.ID_WORKER)
private Long id;
private String name;
private String username;
private String password;
private String phone;
private String sex;
private String idNumber; //身份证号码
private Integer status;
//将时间转换为自己要的时间格式向前端发送(具体还是json数据不变)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT) //插入时填充字段
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
private Date updateTime;
@TableField(fill = FieldFill.INSERT) //插入时填充字段
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
private Long updateUser;
}
FieldFill源码:
/**
* 字段填充策略枚举类
*
* <p>
* 判断注入的 insert 和 update 的 sql 脚本是否在对应情况下忽略掉字段的 if 标签生成
* <if test="...">......</if>
* 判断优先级比 {@link FieldStrategy} 高
* </p>
*
* @author hubin
* @since 2017-06-27
*/
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入时填充字段
*/
INSERT,
/**
* 更新时填充字段
*/
UPDATE,
/**
* 插入和更新时填充字段
*/
INSERT_UPDATE
}
三、导致自动填充失效的原因,以及替代方法
四、对与内置方法详解(源代码)
/**
* 元对象字段填充控制器抽象类,实现公共字段自动写入<p>
* <p>
* 所有入参的 MetaObject 必定是 entity 或其子类的 MetaObject
*
* @author hubin
* @since 2016-08-28
*/
public interface MetaObjectHandler {
/**
* 是否开启了插入填充
*/
default boolean openInsertFill() {
return true;
}
/**
* 是否开启了更新填充
*/
default boolean openUpdateFill() {
return true;
}
/**
* 插入元对象字段填充(用于插入时对公共字段的填充)
*
* @param metaObject 元对象
*/
void insertFill(MetaObject metaObject);
/**
* 更新元对象字段填充(用于更新时对公共字段的填充)
*
* @param metaObject 元对象
*/
void updateFill(MetaObject metaObject);
/**
* 通用填充
*
* @param fieldName java bean property name
* @param fieldVal java bean property value
* @param metaObject meta object parameter
*/
default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
if (Objects.nonNull(fieldVal) && metaObject.hasSetter(fieldName)) {
metaObject.setValue(fieldName, fieldVal);
}
return this;
}
/**
* get value from java bean by propertyName
*
* @param fieldName java bean property name
* @param metaObject parameter wrapper
* @return 字段值
*/
default Object getFieldValByName(String fieldName, MetaObject metaObject) {
return metaObject.hasGetter(fieldName) ? metaObject.getValue(fieldName) : null;
}
/**
* find the tableInfo cache by metaObject </p>
* 获取 TableInfo 缓存
*
* @param metaObject meta object parameter
* @return TableInfo
* @since 3.3.0
*/
default TableInfo findTableInfo(MetaObject metaObject) {
return TableInfoHelper.getTableInfo(metaObject.getOriginalObject().getClass());
}
/**
* @param metaObject metaObject meta object parameter
* @return this
* @since 3.3.0
*/
default <T, E extends T> MetaObjectHandler strictInsertFill(MetaObject metaObject, String fieldName, Class<T> fieldType, E fieldVal) {
return strictInsertFill(findTableInfo(metaObject), metaObject, Collections.singletonList(StrictFill.of(fieldName, fieldType, fieldVal)));
}
/**
* @param metaObject metaObject meta object parameter
* @return this
* @since 3.3.0
*/
default <T, E extends T> MetaObjectHandler strictInsertFill(MetaObject metaObject, String fieldName, Supplier<E> fieldVal, Class<T> fieldType) {
return strictInsertFill(findTableInfo(metaObject), metaObject, Collections.singletonList(StrictFill.of(fieldName, fieldVal, fieldType)));
}
/**
* @param metaObject metaObject meta object parameter
* @return this
* @since 3.3.0
*/
default MetaObjectHandler strictInsertFill(TableInfo tableInfo, MetaObject metaObject, List<StrictFill<?, ?>> strictFills) {
return strictFill(true, tableInfo, metaObject, strictFills);
}
/**
* @param metaObject metaObject meta object parameter
* @return this
* @since 3.3.0
*/
default <T, E extends T> MetaObjectHandler strictUpdateFill(MetaObject metaObject, String fieldName, Supplier<E> fieldVal, Class<T> fieldType) {
return strictUpdateFill(findTableInfo(metaObject), metaObject, Collections.singletonList(StrictFill.of(fieldName, fieldVal, fieldType)));
}
/**
* @param metaObject metaObject meta object parameter
* @return this
* @since 3.3.0
*/
default <T, E extends T> MetaObjectHandler strictUpdateFill(MetaObject metaObject, String fieldName, Class<T> fieldType, E fieldVal) {
return strictUpdateFill(findTableInfo(metaObject), metaObject, Collections.singletonList(StrictFill.of(fieldName, fieldType, fieldVal)));
}
/**
* @param metaObject metaObject meta object parameter
* @return this
* @since 3.3.0
*/
default MetaObjectHandler strictUpdateFill(TableInfo tableInfo, MetaObject metaObject, List<StrictFill<?, ?>> strictFills) {
return strictFill(false, tableInfo, metaObject, strictFills);
}
/**
* 严格填充,只针对非主键的字段,只有该表注解了fill 并且 字段名和字段属性 能匹配到才会进行填充(null 值不填充)
*
* @param insertFill 是否验证在 insert 时填充
* @param tableInfo cache 缓存
* @param metaObject metaObject meta object parameter
* @param strictFills 填充信息
* @return this
* @since 3.3.0
*/
default MetaObjectHandler strictFill(boolean insertFill, TableInfo tableInfo, MetaObject metaObject, List<StrictFill<?, ?>> strictFills) {
if ((insertFill && tableInfo.isWithInsertFill()) || (!insertFill && tableInfo.isWithUpdateFill())) {
strictFills.forEach(i -> {
final String fieldName = i.getFieldName();
final Class<?> fieldType = i.getFieldType();
tableInfo.getFieldList().stream()
.filter(j -> j.getProperty().equals(fieldName) && fieldType.equals(j.getPropertyType()) &&
((insertFill && j.isWithInsertFill()) || (!insertFill && j.isWithUpdateFill()))).findFirst()
.ifPresent(j -> strictFillStrategy(metaObject, fieldName, i.getFieldVal()));
});
}
return this;
}
/**
* 填充策略,默认有值不覆盖,如果提供的值为null也不填充
*
* @param metaObject metaObject meta object parameter
* @param fieldName java bean property name
* @param fieldVal java bean property value of Supplier
* @return this
* @since 3.3.0
*/
default MetaObjectHandler fillStrategy(MetaObject metaObject, String fieldName, Object fieldVal) {
if (getFieldValByName(fieldName, metaObject) == null) {
setFieldValByName(fieldName, fieldVal, metaObject);
}
return this;
}
/**
* 严格模式填充策略,默认有值不覆盖,如果提供的值为null也不填充
*
* @param metaObject metaObject meta object parameter
* @param fieldName java bean property name
* @param fieldVal java bean property value of Supplier
* @return this
* @since 3.3.0
*/
default MetaObjectHandler strictFillStrategy(MetaObject metaObject, String fieldName, Supplier<?> fieldVal) {
if (metaObject.getValue(fieldName) == null) {
Object obj = fieldVal.get();
if (Objects.nonNull(obj)) {
metaObject.setValue(fieldName, obj);
}
}
return this;
}
}
版权声明:本文为A1916403680原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。