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

前言

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

属性填充

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

自定义属性填充器

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

  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类型属性值填充异常");
                }
            }
        }
    }

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

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值