欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MybatisPlus自动填充公共字段及特定类型属性设置默认值

程序员文章站 2022-03-10 18:35:26
前言MybatisPlus是一个 MyBatis的增强工具,集成了mybatis和hibernate各自的优点,所以很受一些企业的喜爱。目前我们公司就在使用,确实特别好用。本文重点介绍自动填充公共字段及特定字段类型设置默认值的方法。之前写过一篇关于JPA和mybatis自动填充的文章,有兴趣的小伙伴可以进行查看:链接属性填充首先MP为我们提供了元数据处理接口MetaObjectHandler,里面提供了很多默认填充实现方法供我们使用。其中insertFill和updateFill是新建和更新的填充方...

前言

MybatisPlus是一个 MyBatis的增强工具,集成了mybatis和hibernate各自的优点,所以很受一些企业的喜爱。目前我们公司就在使用,确实特别好用。本文重点介绍自动填充公共字段及特定字段类型设置默认值的方法。
之前写过一篇关于JPA和mybatis自动填充的文章,有兴趣的小伙伴可以进行查看:链接

属性填充

首先MP为我们提供了元数据处理接口MetaObjectHandler,里面提供了很多默认填充实现方法供我们使用。其中insertFill和updateFill是新建和更新的填充方法,默认没有实现,需要我们自己实现。
MybatisPlus自动填充公共字段及特定类型属性设置默认值
其实现原理和mybatis的一样,在MybatisPlusAutoConfiguration自动配置类里面会根据MetaObjectHandler.class找到相应的Bean,然后配置到全局配置的元对象字段填充控制器属性上。源码如下:
MybatisPlus自动填充公共字段及特定类型属性设置默认值
获取Bean并设置
MybatisPlus自动填充公共字段及特定类型属性设置默认值

自定义属性填充器

直接上代码,注意点如下:

  1. 需要将填充器注入到spring容器,此处直接加@Component。
  2. 填充的fieldName是实体类的属性名,而不是对应表的字段名。
/**
 3. 元对象字段填充控制器
 4. 自定义填充公共字段 ,即没有传的字段自动填充
 5.  6. @author gourd.hu
 **/
@Component
public class FillMetaObjectHandler implements MetaObjectHandler {
    /**
     *  新增填充
     *
     *  @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        JwtToken currentUser = JwtUtil.getCurrentUser();
        // 创建填充
        fillCreateMeta(metaObject, currentUser);
        // 更新填充
        fillUpdateMeta(metaObject, currentUser);
    }

    /**
     * 更新填充
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        JwtToken currentUser = JwtUtil.getCurrentUser();
        fillUpdateMeta(metaObject,currentUser);
    }

    /**
     * 填充创建数据
     * @param metaObject
     * @param currentUser
     */
    private void fillCreateMeta(MetaObject metaObject, JwtToken  currentUser) {
        Long userId = currentUser == null ? 1L: currentUser.getUserId();
        String userName = currentUser == null ? "007": currentUser.getUserName();
        if (metaObject.hasGetter(RbacConstant.META_CREATED_BY) && metaObject.hasGetter(RbacConstant.META_CREATED_TIME)) {
            this.strictInsertFill(metaObject,RbacConstant.META_CREATED_BY,Long.class, userId);
            this.strictInsertFill(metaObject,RbacConstant.META_CREATED_TIME,LocalDateTime.class, LocalDateTime.now());
            this.strictInsertFill(metaObject,RbacConstant.META_DELETED,Boolean.class,Boolean.FALSE);
            this.strictInsertFill(metaObject,RbacConstant.META_VERSION,Integer.class,1);
        }
        if(metaObject.hasGetter(RbacConstant.META_CREATED_NAME)){
            this.strictInsertFill(metaObject,RbacConstant.META_CREATED_NAME,String.class, userName);
        }
    }

    /**
     * 填充更新数据
     * @param metaObject
     * @param currentUser
     */
    private void fillUpdateMeta(MetaObject metaObject, JwtToken currentUser) {
        Long userId = currentUser == null ? 1L: currentUser.getUserId();
        String userName = currentUser == null ? "007": currentUser.getUserName();
        if (metaObject.hasGetter(RbacConstant.META_UPDATED_BY) && metaObject.hasGetter(RbacConstant.META_UPDATED_TIME)) {
            // fillStrategy方法会判断属性是否有值,如果有值就不会覆盖,所以调整为setFieldValByName方法
            this.strictUpdateFill(metaObject,RbacConstant.META_UPDATED_BY,Long.class, userId);
            this.strictUpdateFill(metaObject,RbacConstant.META_UPDATED_TIME,LocalDateTime.class, LocalDateTime.now());
        }
        if(metaObject.hasGetter(RbacConstant.META_UPDATED_NAME)){
            this.strictUpdateFill(metaObject,RbacConstant.META_UPDATED_NAME,String.class, userName);
        }
    }
}

这样就可以实现属性的自动填充了。当然里面的填充逻辑,可以根据自己业务自定义调整。

特定类型属性设置默认值

有些时候,我们需要数据的一些字段不存储null值,我们可以通过给这些字段填充默认值实现。有三种方式:

  1. 数据库字段直接设置默认值,但如果代码中自定义sql插入还是可以填充null值。
  2. 实体属性设置默认值,如 private Integer count=0;但是这种情况在更新的时候,会存在误更新。
  3. 自定义填充器,创建填充时为特定类型设置默认值。
    如下:
 /**
     * 填充创建数据
     * @param metaObject
     * @param currentUser
     */
    private void fillCreateMeta(MetaObject metaObject, JwtToken  currentUser) {
        Long userId = currentUser == null ? 1L: currentUser.getUserId();
        String userName = currentUser == null ? "007": currentUser.getUserName();
        if (metaObject.hasGetter(RbacConstant.META_CREATED_BY) && metaObject.hasGetter(RbacConstant.META_CREATED_TIME)) {
            this.strictInsertFill(metaObject,RbacConstant.META_CREATED_BY,Long.class, userId);
            this.strictInsertFill(metaObject,RbacConstant.META_CREATED_TIME,LocalDateTime.class, LocalDateTime.now());
            this.strictInsertFill(metaObject,RbacConstant.META_DELETED,Boolean.class,Boolean.FALSE);
            this.strictInsertFill(metaObject,RbacConstant.META_VERSION,Integer.class,1);
        }
        if(metaObject.hasGetter(RbacConstant.META_CREATED_NAME)){
            this.strictInsertFill(metaObject,RbacConstant.META_CREATED_NAME,String.class, userName);
        }
        // 插入数据,Integer默认设置0,String类型默认设置空字符串
        List<TableFieldInfo> fieldList = this.findTableInfo(metaObject).getFieldList();
        Object originalObject = metaObject.getOriginalObject();
        for (TableFieldInfo fieldInfo : fieldList) {
            if(Integer.class.equals(fieldInfo.getPropertyType())){
                try {
                    Object o = fieldInfo.getField().get(originalObject);
                    if(o == null){
                        this.strictInsertFill(metaObject,fieldInfo.getProperty(), Integer.class,0);
                    }
                } catch (IllegalAccessException e) {
                    log.error("Integer类型属性值填充异常");
                }
            }
            if(String.class.equals(fieldInfo.getPropertyType())){
                try {
                    Object o = fieldInfo.getField().get(originalObject);
                    if(o == null){
                        this.strictInsertFill(metaObject,fieldInfo.getProperty(), String.class,"");
                    }
                } catch (IllegalAccessException e) {
                    log.error("String类型属性值填充异常");
                }
            }
        }
    }

这样就实现了特定类型属性设置默认值,如果你有更好的方式,欢迎评论告知。

本文地址:https://blog.csdn.net/HXNLYW/article/details/112600665