MyBatis與Spring設置callSettersOnNulls



項目中集成Mybatis與Spring,使用的是Mybatis3.2.7,以及Spring4.0.5,mybatis-spring-1.2.2;
因為項目組成員想要偷懶,將數據從DB中查詢出來時需要將字段映射為Map,而不想封裝成Bean.

默認情況下,Mybatis對Map的解析生成, 如果值(value)為null的話,那么key也不會被加入到map中.
於是對Map遍歷時,key就遍歷不到,因為前端工具的需要,必須有這個key,網上搜索后發現需要設置 callSettersOnNulls 這個屬性.
那就設置唄, 在 sqlSessionFactory 的定義中,指定 configLocation 屬性,指向另一個文件,如下所示

文件清單: mybatis-env-setting.xml
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE configuration   
  3.     PUBLIC "-//mybatis.org//DTD Config 3.0//EN"   
  4.     "http://mybatis.org/dtd/mybatis-3-config.dtd">   
  5.   
  6. <!--  
  7.     如果內網機器報錯,請使用下面這種笨辦法 
  8.  -->  
  9. <!--   
  10. <!DOCTYPE configuration  
  11.         PUBLIC "-//www.mybatis.org//DTD Config 3.0//EN"  
  12.         "E:/bao/tomcat/apache-tomcat-6.0.14/webapps/pmsys/WEB-INF/classes/mybatis/mybatis-3-config.dtd">  
  13.  -->  
  14.   
  15. <configuration>  
  16.     <settings>  
  17.       <!-- 只設置需要的,其他使用默認值 -->  
  18.       <!-- 開啟緩存,默認就是開啟的,2層開關,需要在Mapper文件中也指定 cache 標簽才會真正使用緩存 -->  
  19.       <setting name="cacheEnabled" value="true"/>  
  20.       <!-- 在null時也調用 setter,適應於返回Map,3.2版本以上可用 -->  
  21.         <setting name="callSettersOnNulls" value="true"/>  
  22.     </settings>  
  23. </configuration>  

然后使用,一切正常,OK.
過了幾天, 實施項目時出BUG了, 因為是企業內網服務器,不能訪問 mybatis.org,於是啟動出錯.
【Mybatis 這個渣渣,在啟動時會去獲取並校驗DTD,目前還不知道在哪里配置讓其不進行校驗.】
網上搜索半天,沒有好的解決辦法, 看到有方法說將dtd下載到本地,然后直接指定路徑,就像上面注釋掉的那部分一樣。

問題也算是解決了,可是很土,而且各個機器不一定都有同樣的目錄,這種掉渣的方法肯定會遭人詬病的。
於是百度谷歌又搜索了半天,沒找到辦法,根本沒有人提這茬。

於是想着自己翻源碼看看:
  1. public class SqlSessionFactoryBean   
  2.     implements FactoryBean<SqlSessionFactory>, InitializingBean,   
  3.     ApplicationListener<ApplicationEvent> {  
  4.   
  5.   private static final Log logger = LogFactory.getLog(SqlSessionFactoryBean.class);  
  6.   // 這里可以配置configLocation資源  
  7.   private Resource configLocation;  
  8.   
  9.   private Resource[] mapperLocations;  
  10.   
  11.   private DataSource dataSource;  
  12.   
  13.   private TransactionFactory transactionFactory;  
  14.   // 這里可以配置configurationProperties屬性  
  15.   private Properties configurationProperties;  
  16.   
  17.   ......  
  18.   
  19.   protected SqlSessionFactory buildSqlSessionFactory() throws IOException {  
  20.   
  21.     Configuration configuration;  
  22.   
  23.     XMLConfigBuilder xmlConfigBuilder = null;  
  24.     // 先查找 configLocation 屬性  
  25.     if (this.configLocation != null) {  
  26.       xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), nullthis.configurationProperties);  
  27.       configuration = xmlConfigBuilder.getConfiguration();  
  28.     } else {  
  29.       if (logger.isDebugEnabled()) {  
  30.         logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");  
  31.       }  
  32.       // 如果找不到configLocation,就只使用 configurationProperties  
  33.       configuration = new Configuration();  
  34.       configuration.setVariables(this.configurationProperties);  
  35.     }  
  36.   
  37.     ......  

啟動沒報錯,但是還沒檢驗.應該沒多大問題...

補充: 還是不起作用,於是沒法子了,只好拆開Mybatis的源碼,找到類 org.apache.ibatis.session.Configuration ,然后,在自己的目錄下把源碼拷出來, 自己在test目錄建一個包,建一個類,和Configuration一模一樣,然后修改 callSettersOnNulls 的默認值為 true,然后找到編譯好的3個class文件(有內部類),替換到mybatis-3.2.7.jar中去,OK,成功解決。

按理說應該是編譯整個mybatis的,但是maven有點坑,目前還不想這樣做

看了 mybatis高級應用系列一:分頁功能 這篇文章,發覺冤枉 MyBatis了,其實是 Mybatis-Spring挖下的坑, 校驗的時候不走Mybatis的默認通道, 而是自己解析了對應的XML文件,還要去網上搜索dtd文件,巨坑無比啊.

給了 configurationProperties 這么個選項,卻不使用,真是不好。

附上一篇, 如何解決Spring附加組件中dtd的這種坑



免責聲明!

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



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