碰見這個問題,是公司的小夥伴跟我說,每次使用mybatis的時候,簡單的連表查詢,用Map接收的時候,都是像DB定義的字段同樣,相似如下 student_name,student_id,沒有轉換爲駝峯,可是又不能由於這一個定義一個javabean來映射數據庫字段集合,這樣,會有無窮無盡的javabean,徹底不是辦法,而後我看了下mybatis-spring-boot的配置文檔http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/,發現有這麼個屬性 html
mybatis.configuration.map-underscore-to-camel-case=true看着屬性意思,很像是 map 下劃線轉換爲駝峯,而後我天真的覺得,加個這個,就會將Map裏面的key轉換爲駝峯的命名方式,而後我本身測試了一下,發現本身仍是太天真,沒轉過來,該是什麼仍是什麼(內心面是B了狗了)....java
沒辦法,接着找了了一下,發現官方文檔http://www.mybatis.org/mybatis-3/configuration.html#properties,描述過這個的做用 spring
才發現,這個屬性的做用,是做用於javabean的field的,並非map,ㄟ( ▔, ▔ )ㄏ,那沒辦法了,只能本身動手了數據庫
-------------------------------我是分割線--------------------------------------apache
既然 map-underscore-to-camel-case 不能做用於map,那麼只能本身動手了,而後我就想到了2個解決方案:session
- 繼承HashMap,重寫Put函數,將mybatis返回的Map,寫上自定義Map的路徑,自定義的Map,將全部的key內部轉換爲駝峯表達式
- 找到mybatis的Handler,經過Handler來找到轉換映射關係的接口定義,繼承或者實現接口,而後走自定義的轉換規則來實現Map映射的駝峯轉換
最終決定,採用第二種,方便之後擴展,以及項目結構mybatis
首先,我開始找mybatis的configuration裏面的mapUnderscoreToCamelCase屬性調用的地方app
有兩個地方調用了,而後咱們看第一個調用的地方,發現名稱是createAutomaticMappings,應該是map的映射字段建立沒跑了,以下代碼,光標顯示的地方,就是調用的地方ide
而後咱們在查看屬性傳遞進去後的操做,點進 metaObject.findProperty的實現函數
接着在看,objectWrapper.findProperty,發現是個接口,而後咱們須要查看,是對應的哪一個實現,而後我debug發現是 MapWrapper的實現,並無作任何操做,直接返回了name
到這裏,我點開了下源碼的目錄結構,發現瞭如下
內心大概明白怎麼回事了,具體過程應該以下
經過接口ObjectWrapper來定義行爲,有默認的一些實現,而後經過工廠ObjectWrapperFactory接口,來建立ObjectWrapper接口,最後來進行對方的自動映射跟包裝,自此,內心已經想到怎麼改動了
public class CustomWrapper extends MapWrapper{ public CustomWrapper(MetaObject metaObject, Map<String, Object> map) { super(metaObject, map); } @Override public String findProperty(String name, boolean useCamelCaseMapping) { if(useCamelCaseMapping){ //CaseFormat是引用的 guava庫,裏面有轉換駝峯的,省得本身重複造輪子,pom添加 /** ** <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>24.1-jre</version> </dependency> **/ return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,name); } return name; } }
public class MapWrapperFactory implements ObjectWrapperFactory { @Override public boolean hasWrapperFor(Object object) { return object != null && object instanceof Map; } @Override public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) { return new CustomWrapper(metaObject,(Map)object); } }
@Configuration public class MybatisConfig { @Bean public ConfigurationCustomizer mybatisConfigurationCustomizer(){ return new ConfigurationCustomizer() { @Override public void customize(org.apache.ibatis.session.Configuration configuration) { configuration.setObjectWrapperFactory(new MapWrapperFactory()); } }; } }
作了以上操做後,咱們就將默認的Map映射,的包裝類,查找property的部分,變成了本身想要的樣子,
最後,咱們在 properties或者yml裏面加上 mybatis.configuration.map-underscore-to-camel-case=true ,畢竟在CustomerWrapper裏面,咱們是經過使用這個來控制是否轉換駝峯的,最後寫個測試用例跑一下,而後會發現,之前db的字段,下劃線已經轉換成駝峯命名了
到這,文章就結束了!
以上,均爲本人測試而得出的結果,可能會有出入,或者錯誤,歡迎指正
歡迎轉載,請註明出處跟做者,謝謝!