当前位置: 首页 > 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/news/319175.html

相关文章:

  • 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张
  • LeetCode2207解题思路
  • 双十一买什么好?五款数码好物推荐!
  • 毕业设计选题:基于ssm+vue+uniapp的面向企事业单位的项目申报小程序
  • 1.3 MySql的用户管理
  • 电脑如何录屏?无水印、高清晰度电脑录屏教程
  • 『功能项目』QFrameWork道具栏物品生成【64】
  • thinkphp8 从入门到放弃(后面会完善用到哪里写到哪)
  • C#图像爬虫实战:从Walmart网站下载图片
  • python常见的魔术方法
  • 对FPGA加载过程中不同寄存器初始化方式现象的分析