当前位置: 首页 > article >正文

mybatis-plus公共字段自动填充fillStrategy()方法和strictFill()方法

前言:在mybatis-plus的公共字段自动填充功能中有多种填充方式,以下将通过源码对各种填充方法进行剖析

相信了解mybatis-plus公共字段自动填充功能的同学对MetaObjectHandler接口并不陌生,我们把MetaObjectHandler接口整理一下,只关注他的注入字段部分(结论在下面)

public interface MetaObjectHandler {

    default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
        if (Objects.nonNull(fieldVal) && metaObject.hasSetter(fieldName)) {
            metaObject.setValue(fieldName, fieldVal);
        }
        return this;
    }

    default MetaObjectHandler strictInsertFill(TableInfo tableInfo, MetaObject metaObject, List<StrictFill<?, ?>> strictFills) {
        return strictFill(true, tableInfo, metaObject, strictFills);
    }

    default MetaObjectHandler strictUpdateFill(TableInfo tableInfo, MetaObject metaObject, List<StrictFill<?, ?>> strictFills) {
        return strictFill(false, tableInfo, metaObject, strictFills);
    }

    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;
    }

    default MetaObjectHandler fillStrategy(MetaObject metaObject, String fieldName, Object fieldVal) {
        if (getFieldValByName(fieldName, metaObject) == null) {
            setFieldValByName(fieldName, fieldVal, metaObject);
        }
        return this;
    }

    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;
    }
}

此时有6个方法可以进行字段填充

  • setFieldValByName()
  • strictInsertFill()
  • strictUpdateFill()
  • strictFill()
  • fillStrategy()
  • strictFillStrategy()

我们逐个进行分析

  • setFieldValByName()
    当要注入的值fieldVal不为空,则注入,被fillStrategy()方法代替
  • strictInsertFill()
  • strictUpdateFill()
    以上两个方法都是直接封装后调用strictFille(),可以忽略
  • strictFill()
    校验实体表里的字段与要注入的公共字段的数据的名称和类型是否一致、实体类上是否有@TableField(fill = FieldFill.xxx)注解,再调用strictFillStrategy()方法进行填充
  • fillStrategy()
    在直接调用setFieldValByName()的基础上,做了一层安全校验
    若元数据的该字段为null,且fieldVal不为空才注入
  • strictFillStrategy()
    若元数据的该字段为null,且fieldVal不为空才注入,被strictFill()方法代替

由于fillStrategy()strictFillStrategy()比较相似,可以一下比较这两个方法

default MetaObjectHandler fillStrategy(MetaObject metaObject, String fieldName, Object fieldVal) {
  //把getFieldValByName()和setFieldValByName()方法体内的代码进行替换并简化
  if (metaObject.getValue(fieldName) == null) {
      if (Objects.nonNull(fieldVal)) {
        metaObject.setValue(fieldName, fieldVal);
    }
  }
  return this;
}

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;
}

可以看出两个方法只在参数fieldVal上有区别
相比之下strictFillStrategy()fieldVal的校验上更加严格

此时可用的方法只剩strictFill()fillStrategy(),两个方法的不同点在于:
strictFill()的安全校验包含了fillStrategy()的安全校验,同时也判断了数据库中是否有这个字段、实体类上是否有@TableField(fill = FieldFill.xxx)注解


http://www.kler.cn/a/319175.html

相关文章:

  • 两种鼠标hover切换对应图片方法对比
  • unity单例模式的不同声明(待完善
  • 【力扣热题100】[Java版] 刷题笔记-169. 多数元素
  • mysql 配置文件 my.cnf 增加 lower_case_table_names = 1 服务启动不了的原因
  • 基于OpenCV的自制Python访客识别程序
  • 代码随想录第二十一天| 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树
  • Windows环境运行.sh脚本提示找不到wget指令的问题
  • CSS基本概念以及CSS的多种引入方式
  • Python模拟真人鼠标轨迹算法
  • 使用umy-ui 优化带有大量输入框、下拉框的ElementUI el-table
  • Leetcode 1472. 设计浏览器历史记录
  • 开源音频处理项目推荐【持续更新】
  • 《C++设计新思维-泛型编程与设计模式之应用》阅读记录
  • DY按图搜索商品API:解锁电商新趋势
  • LeetCode 257. 二叉树的所有路径,dfs
  • 29. RabbitMQ队列模型
  • 多用户自定义商城小程序源码系统 独立部署 到源代码包以及搭建部署教程
  • 根据源码解析Vue2中对于对象的变化侦测
  • 搭建HAproxy----7层负载均衡集群
  • FDA辅料数据库在线免费查询-药用辅料
  • 灵当CRM multipleUpload.php 文件上传致RCE漏洞复现
  • 双11好物推荐有哪些?五大双十一好货推荐!
  • PHP如何从字符串中删除转义字符
  • 抽奖拼团卷轴模式系统开发小程序源代码解析
  • Flask 第十二课 -- 错误处理
  • 下水道内缺陷识别检测数据集 yolo数据集 共2300张