MetaObjectHandler:实体对象的属性自动赋值

发布时间 2023-10-11 16:07:54作者: BlogMemory

1.MetaObjectHandler接口方法

Mybatis中的MetaObjectHandler是一个接口,用于为实体对象的属性自动赋值。它有以下几个方法:

  1. insertFill(MetaObject metaObject):在执行插入操作时自动填充实体对象的属性值。

  2. updateFill(MetaObject metaObject):在执行更新操作时自动填充实体对象的属性值。

  3. strictInsertFill(MetaObject metaObject, String propertyName, Class<?> propertyType, Object propertyValue):在执行插入操作时强制填充实体对象的属性值。

  4. strictUpdateFill(MetaObject metaObject, String propertyName, Class<?> propertyType, Object propertyValue):在执行更新操作时强制填充实体对象的属性值。

  5. setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject):手动设置实体对象的属性值。

  6. getFieldValByName(String fieldName, MetaObject metaObject):获取实体对象的属性值。

  7. getSetterNames():获取实体对象所有setter方法的名称。

  8. getGetterNames():获取实体对象所有getter方法的名称。

  9. getSetterType(String name):获取实体对象指定setter方法的参数类型。

  10. getGetterType(String name):获取实体对象指定getter方法的返回类型。

以上就是Mybatis中MetaObjectHandler的所有方法。通过实现MetaObjectHandler接口并重写这些方法,我们可以为实体对象自动填充属性值,从而简化开发。

 

2.strictInsertFill方法和setFieldValByName方法的主要区别

MetaObjectHandler是Mybatis-Plus提供的一个接口,用于实现自定义的元对象处理器。其中,strictInsertFill方法和setFieldValByName方法的主要区别在于:

  1. strictInsertFill方法用于在执行插入操作时,自动填充指定的字段值。这个方法会先判断实体类中是否存在指定的字段,如果存在则将指定的字段值填充到实体类中,如果不存在则不进行任何操作。

  2. setFieldValByName方法用于设置实体类中指定字段的值。这个方法不会进行任何判断,只要实体类中存在指定的字段,就会将指定的值设置到这个字段中。

因此,strictInsertFill方法更加适合在插入操作时自动填充字段值,而setFieldValByName方法更加灵活,可以用于设置实体类中任意字段的值。

 

3.在实体类中使用 @TableField 注解来标注需要自动填充的字段


@Data
@TableName("user")
public class User {

    /**
     * 创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime creationDate;

    /**
     * 创建人名称
     */
    @TableField(fill = FieldFill.INSERT)
    private String createdBy;

    /**
     * 最后更新时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime lastUpdateDate;

    /**
     * 最后更新人名称
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String lastUpdatedBy;

}

在这个实体类中,我们通过 @TableField 注解来标注需要自动填充的字段。这样,当我们插入或更新数据时,MyBatis 就会自动调用 MyMetaObjectHandler 中的 insertFill 和 updateFill 方法,来填充对应字段。

需要注意的是,MetaObjectHandler 只能对实体类中的属性进行填充,它无法对数据库中的字段进行操作。如果需要对数据库字段进行操作,可以使用 MyBatis 提供的 SQL 函数来实现。

4.自定义类DbFieldFillHandler实现接口MetaObjectHandler 

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.midea.fap.aic.common.constant.DbConstant;
import com.midea.logging.Logger;
import com.midea.logging.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;

import static *.enums.SpecialFieldEnum.CREATED_BY;
import static *.enums.SpecialFieldEnum.CREATION_DATE;
import static *.enums.SpecialFieldEnum.DATA_VERSION;
import static *.enums.SpecialFieldEnum.DELETE_FLAG;
import static *.enums.SpecialFieldEnum.LAST_UPDATED_BY;
import static *.enums.SpecialFieldEnum.LAST_UPDATE_DATE;

/**
 * @version 1.0
 * @date 2023-04-28 14:26
 */
@Slf4j
@Component
public class DbFieldFillHandler implements MetaObjectHandler {

    private static final Logger LOG = LoggerFactory.getLogger(DbFieldFillHandler.class);

    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        if (Objects.isNull(metaObject.getValue(CREATION_DATE.getFieldName()))) {
            this.strictInsertFill(metaObject, CREATION_DATE.getFieldName(), LocalDateTime.class, now);
        }
        if (hasNoText(metaObject.getValue(CREATED_BY.getFieldName()))) {
            this.strictInsertFill(metaObject, CREATED_BY.getFieldName(), String.class, DbConstant.FAP_ADMIN);
        }
        if (Objects.isNull(metaObject.getValue(LAST_UPDATE_DATE.getFieldName()))) {
            this.strictInsertFill(metaObject, LAST_UPDATE_DATE.getFieldName(), LocalDateTime.class, now);
        }
        if (hasNoText(metaObject.getValue(LAST_UPDATED_BY.getFieldName()))) {
            this.strictInsertFill(metaObject, LAST_UPDATED_BY.getFieldName(), String.class, DbConstant.FAP_ADMIN);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        if (Objects.isNull(metaObject.getValue(LAST_UPDATE_DATE.getFieldName()))) {
            this.strictInsertFill(metaObject, LAST_UPDATE_DATE.getFieldName(), LocalDateTime.class, now);
        }
        if (hasNoText(metaObject.getValue(LAST_UPDATED_BY.getFieldName()))) {
            this.strictInsertFill(metaObject, LAST_UPDATED_BY.getFieldName(), String.class, DbConstant.FAP_ADMIN);
        }
    }

    private boolean hasNoText(Object obj) {
        return null == obj || !StrUtil.isNotBlank(obj.toString());
    }
}


/**
 * 审计字段
 *
 */
public enum SpecialFieldEnum {

    /**
     * 创建时间
     */
    CREATION_DATE("creation_date", "creationDate"),
    /**
     * 创建人
     */
    CREATED_BY("created_by", "createdBy"),
    /**
     * 更新人
     */
    LAST_UPDATED_BY("last_updated_by", "lastUpdatedBy"),
    /**
     * 更新时间
     */
    LAST_UPDATE_DATE("last_update_date", "lastUpdateDate"),
    /**
     * 逻辑删除标识
     */
    DELETE_FLAG("delete_flag", "deleteFlag"),
    /**
     * 版本
     */
    DATA_VERSION("data_version", "dataVersion");

    private String columnName;
    private String fieldName;

    private SpecialFieldEnum(String columnName, String fieldName) {
        this.columnName = columnName;
        this.fieldName = fieldName;
    }

    public String getColumnName() {
        return this.columnName;
    }

    public String getFieldName() {
        return this.fieldName;
    }
}

 5.配置文件加入DbFieldFillHandler

 


import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.midea.fap.aic.infra.handler.DbFieldFillHandler;
import org.springframework.context.annotation.Bean;

/**
 * Mybatis 配置
 */
public class MybatisConfig {

    @Bean
    public MetaObjectHandler dbFieldFillHandler() {
        return new DbFieldFillHandler();
    }
}