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

總結

對於不清楚的配置不能囫圇吞棗,否則容易釀成大禍。

參考文獻






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM