mybatis會自動把字段名中的下划線轉為駝峰命名法?


 

先看一下轉化的調用堆棧:
代碼如下:
上面代碼只是去掉了下划線,並沒有首字母小寫變大寫的代碼。再跟進findProperty方法可以找到獲取駝峰結果的代碼如下:
可以看出通過reflector.findPropertyName方法把去掉下划線的變量轉成了駝峰的變量。再跟過去看到這樣的代碼:

那么caseInsensitivePropertyMap這個集合又是什么時候初始化的呢?原來是系統啟動時,spring加載上下文的時候:
而它的key其實是實體類的set與get方法后面的字符(org.apache.ibatis.reflection.Reflector.addGetMethods,org.apache.ibatis.reflection.property.PropertyNamer.methodToProperty),而這個方法一般都是標准的駝峰格式。所以當get(大寫字段)名時,可以得到標准的駝峰字段名。

 

 

 PropertyTokenizer類

   這個類是property包中的重量級類,該類會被reflection包中其他的類頻繁的引用到。這個類實現了Iterable和Iterator這兩個接口,但在使用時經常被用到的是Iterator接口中的hasNext這個函數。我們着重了解這個類的屬性和構造函數:

復制代碼
//包含四個屬性,比較簡單
    private String name;
    private String index;
    private String indexedName;
    private String children;

    public PropertyTokenizer(String propertyName) {
        // 對參數進行第一次處理,通過“.”分隔符將propertyName分作兩部分
        int delimiter = propertyName.indexOf(".");
        if (delimiter > -1) {
            name = propertyName.substring(0, delimiter);
            children = propertyName.substring(delimiter + 1);
        } else {
            name = propertyName;
            children = null;
        }
        indexedName = name;
        // 對name進行二次處理,去除“[...]”,並將方括號內的內容賦給index屬性,如果name屬性中包含“[]”的話
        delimiter = propertyName.indexOf("[");
        if (delimiter > -1) {
            // 先取index內容再截取name更為方便些,要不然還需要一個臨時變量,需要三步才能實現
            // 這里包含了一個前提:傳入的參數如果有有[,則必然存在],並且是屬性的最后一個字符
            index = name.substring(delimiter + 1, name.length() - 1);
            name = name.substring(0, delimiter);
        }
    }
復制代碼

經常使用的hasNext函數實現比較簡單,就是判斷children屬性是不是為空:

public boolean hasNext() {
        // TODO Auto-generated method stub
        return children != null;
    }


 

Mybatis 之mapUnderscoreToCamelCase

版權聲明:本文為博主原創文章,遵循 CC 4.0 by-sa 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接: https://blog.csdn.net/jueyue/article/details/43617383

之前用spring jdbc的時候發下spring可以駝峰轉換,所以一直希望mybatis也有,之前還以為mybatis這個是個bug,后來發現原來也是有的,用起來也是很簡單的,setting設置下就可以了,這里就不說了,下面說下是怎么實現的

 

 

  1.  
    public String findProperty(String name) {
  2.  
    StringBuilder prop = buildProperty(name, new StringBuilder());
  3.  
    return prop.length() > 0 ?prop.toString() : null;
  4.  
    }
  5.  
     
  6.  
    public String findProperty(String name,boolean useCamelCaseMapping) {
  7.  
    if (useCamelCaseMapping) {
  8.  
    name = name.replace( "_", "");
  9.  
    }
  10.  
    return findProperty(name);
  11.  
    }


 

如果我們設置了,useCamelCaseMapping=ture,那么mybatis就把_給干掉了,看到這里我也很疑惑,還以為是坑爹呢,

我們接着往下看,buildProperty

 

  1.  
    private StringBuilderbuildProperty( String name, StringBuilder builder) {
  2.  
    PropertyTokenizer prop = newPropertyTokenizer(name);
  3.  
    if (prop.hasNext()) {
  4.  
    String propertyName =reflector.findPropertyName(prop.getName());
  5.  
    if (propertyName != null) {
  6.  
    builder.append(propertyName);
  7.  
    builder.append( ".");
  8.  
    MetaClass metaProp =metaClassForProperty(propertyName);
  9.  
    metaProp.buildProperty(prop.getChildren(), builder);
  10.  
    }
  11.  
    } else {
  12.  
    String propertyName =reflector.findPropertyName(name);
  13.  
    if (propertyName != null) {
  14.  
    builder.append(propertyName);
  15.  
    }
  16.  
    }
  17.  
    return builder;
  18.  
    }


其實是從reflector獲取的數據,做個reflector是干嘛的呢,其實就是mybatis來存儲class信息的,也可以說是mybatis的反射工具類

 

Reflector里面

public StringfindPropertyName(String name) {

    returncaseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH));

  }

做個toUpperCase是個關鍵,他忽略了我們類里面的屬性值,也就是說我們一個id和一個ID屬性,對於mybatis來說可能是一直的呦

 

private Map<String, String>caseInsensitivePropertyMap = new HashMap<String, String>();

存儲的就是field upperCaseName和真實的Name 也就是我們的駝峰轉換,或者其實不對稱的駝峰也是可以的,只要把_去掉,應該就可以拿到的

再把整個流程整理一下:

 

 

所以其實不是轉換下划線,而是去掉下划線,再取駝峰的變量。不過最后的效果與轉換的一樣。

 

Mybatis 之mapUnderscoreToCamelCase

版權聲明:本文為博主原創文章,遵循 CC 4.0 by-sa 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接: https://blog.csdn.net/jueyue/article/details/43617383

之前用spring jdbc的時候發下spring可以駝峰轉換,所以一直希望mybatis也有,之前還以為mybatis這個是個bug,后來發現原來也是有的,用起來也是很簡單的,setting設置下就可以了,這里就不說了,下面說下是怎么實現的

 

 

  1.  
    public String findProperty(String name) {
  2.  
    StringBuilder prop = buildProperty(name, new StringBuilder());
  3.  
    return prop.length() > 0 ?prop.toString() : null;
  4.  
    }
  5.  
     
  6.  
    public String findProperty(String name,boolean useCamelCaseMapping) {
  7.  
    if (useCamelCaseMapping) {
  8.  
    name = name.replace( "_", "");
  9.  
    }
  10.  
    return findProperty(name);
  11.  
    }


 

如果我們設置了,useCamelCaseMapping=ture,那么mybatis就把_給干掉了,看到這里我也很疑惑,還以為是坑爹呢,

我們接着往下看,buildProperty

 

  1.  
    private StringBuilderbuildProperty( String name, StringBuilder builder) {
  2.  
    PropertyTokenizer prop = newPropertyTokenizer(name);
  3.  
    if (prop.hasNext()) {
  4.  
    String propertyName =reflector.findPropertyName(prop.getName());
  5.  
    if (propertyName != null) {
  6.  
    builder.append(propertyName);
  7.  
    builder.append( ".");
  8.  
    MetaClass metaProp =metaClassForProperty(propertyName);
  9.  
    metaProp.buildProperty(prop.getChildren(), builder);
  10.  
    }
  11.  
    } else {
  12.  
    String propertyName =reflector.findPropertyName(name);
  13.  
    if (propertyName != null) {
  14.  
    builder.append(propertyName);
  15.  
    }
  16.  
    }
  17.  
    return builder;
  18.  
    }


其實是從reflector獲取的數據,做個reflector是干嘛的呢,其實就是mybatis來存儲class信息的,也可以說是mybatis的反射工具類

 

Reflector里面

public StringfindPropertyName(String name) {

    returncaseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH));

  }

做個toUpperCase是個關鍵,他忽略了我們類里面的屬性值,也就是說我們一個id和一個ID屬性,對於mybatis來說可能是一直的呦

 

private Map<String, String>caseInsensitivePropertyMap = new HashMap<String, String>();

存儲的就是field upperCaseName和真實的Name 也就是我們的駝峰轉換,或者其實不對稱的駝峰也是可以的,只要把_去掉,應該就可以拿到的


免責聲明!

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



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