MybatisPlus的FieldStrategy

起源

今天在新项目中打算使用Mybatis Plus3.x版本,然后发现2.x版本中有些配置被废弃了。其中一个field-strategy引起了注意。
一时偷懒可能会导致线上问题,所以还是研究一下。

正文

MP中,该设置会影响sql语句的拼接行为。在2.x版本中,没有对这个进行区分,不可单独设置字段策略。
下面通过具体的配置来解释差异

# 2.x配置
mybatis-plus:
  mapper-locations:
    - classpath*:mapper/**/*Mapper.xml
  typeAliasesPackage: com.test.assist.dao.domain
  global-config:
    id-type: 0
    field-strategy: 2
    db-column-underline: true
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
#3.x的配置
mybatis-plus:
  typeAliasesPackage: com.test.assist.dao.domain
  mapper-locations:
    - classpath*:mapper/**/*Mapper.xml
  global-config:
    db-config:
      select-strategy: not_empty
      insert-strategy: not_empty
      update-strategy: not_empty
      id-type: auto
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
public enum FieldStrategy {
    IGNORED,
    NOT_NULL,
    NOT_EMPTY,
    DEFAULT,
    NEVER;

    private FieldStrategy() {
    }
}

通过查阅资料和翻看源码,发现这个字段主要会影响sql拼接。我们知道,当通过Entity对表进行更新时,只会更新非空字段。对于那些值为NULL的字段是不会出现在sql语句里的。
下面我从源码里面截取了一段

protected String convertIfTag(boolean ignored, TableFieldInfo fieldInfo, String prefix, boolean close) {
        FieldStrategy fieldStrategy = fieldInfo.getFieldStrategy();
        //如果字段策略为忽略,进行相应的处理
        if (fieldStrategy == FieldStrategy.IGNORED) {
            if (ignored) {
                return "";
            }

            fieldStrategy = this.getGlobalConfig().getFieldStrategy();
        }

        if (close) {
            return "</if>";
        } else {
            String property = fieldInfo.getProperty();
            Class propertyType = fieldInfo.getPropertyType();
            property = StringUtils.removeIsPrefixIfBoolean(property, propertyType);
            if (null != prefix) {
                property = prefix + property;
            }
            //重点是这里,如果字段策略为NOT_EMPTY,那么会对当前字段的值进行判断
            if (fieldStrategy == FieldStrategy.NOT_EMPTY) {
                return StringUtils.isCharSequence(propertyType) ? String.format("\n\t<if test=\"%s!=null and %s!=''\">", property, property) : String.format("\n\t<if test=\"%s!=null \">", property);
            } else {
                return String.format("\n\t<if test=\"%s!=null\">", property);
            }
        }
    }

通过上面的代码可以总结出:

  • NOT_EMPTY:会对字段值进行null和'' 比较操作
  • NOT_NULL: 只会进行null检查

同时在3.x版本中,支持对selectupdateinsert设置不同的字段策略,由此看来大家对这种一刀切的行为还是比较反感的。这一点,我在github也看到issue

总结

对于不清楚的配置不能囫囵吞枣,否则容易酿成大祸。

参考文献





posted @ 2020-04-09 21:48  aibilim  阅读(8471)  评论(0编辑  收藏  举报