• 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的这种坑


  • 相关阅读:
    052-14
    052-13
    css垂直居中
    js中的null 和undefined
    给数组添加属性
    js中避免函数名和变量名跟别人冲突
    js变量问题
    Life
    BFC和haslayout
    json文件
  • 原文地址:https://www.cnblogs.com/jpfss/p/7880158.html
Copyright © 2020-2023  润新知