Mybatis resultMap空值映射问题解决

last 发布于 2015/02/02 10:14
阅读 32K+
收藏 7

Mybatis在使用resultMap来映射查询结果中的列,如果查询结果中包含空值的列(不是null),则Mybatis在映射的时候,不会映射这个字段,例如 查询 name,sex,age,数据库中的age字段没有值,Mybatis返回的map中只映射了 name和sex字段,而age字段则没有包含。

那么如何将age字段映射到map中呢。提供两种解决方法:

使用Mybatis config配置

创建configuration.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL MAP Config 3.1//EN" 
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <settings>
      <setting name="callSettersOnNulls" value="true"/>
  </settings>
</configuration>

配置Mybatis的SqlSessionFactoryBean

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:/META-INF/spring/configuration.    xml" />
    <property name="mapperLocations"
    value="classpath:/META-INF/spring/mybatis/modelMap/*.xml" />
</bean>

在这种配置中,age将以null值映射到map中。

如果想要配置age的默认值,则可以建立一个类,实现Mybatis的TypeHandler接口


public class EmptyStringIfNull implements TypeHandler<String> {

    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
	 return (rs.getString(columnName) == null) ? "" : rs.getString(columnName); 
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
	 return (rs.getString(columnIndex) == null) ? "" : rs.getString(columnIndex);
    }
    @Override
    public String getResult(CallableStatement cs, int columnIndex)   throws SQLException {
	 return (cs.getString(columnIndex) == null) ? "" : cs.getString(columnIndex);
    }
    @Override
    public void setParameter(PreparedStatement ps, int arg1, String str, JdbcType jdbcType) throws SQLException { }}

继续在resultMap中使用,即可配置age的默认值(上述代码中age的默认值为"")

<resultMap id="list" type="java.util.LinkedHashMap">
    <result property="name" column="name" />
    <result property="sex" column="sex" />
    <result property="age" column="age" typeHandler="com.demo.EmptyStringIfNull"/>
</resultMap>



网上有些资料中提到可以使用 defaultValue 和 nullValue的配置,但是这中配置是ibatis的用法,在Mybatis中已经移除。

参考链接http://stackoverflow.com/questions/22852383/how-to-change-valuenull-to-empty-string-from-query-when-using-mybatis

加载中
0
似是而非Sage
似是而非Sage
TypeHandler是比较靠谱的方案,个人认为
last
last
恩,我也是这么觉得的,但是最后采用的是configuration这种方式,typehandler需要在每个有可能为空的列上都进行配置,这个需要去改以前已经写好的文件 -.- 所以就没有采用typehandler。
0
xyxo
xyxo

你的resultMap一定要把type设为LinkedHashMap?

为何不能type =“你定义的object”?

从你的代码片段看,你无非就是想查询到一个list 集合。。而这个list 难道就不能是一个个object?

你把映射类型改为定义的对象,这问题不就解决了么?


CDD
CDD
回复 @last : 使用map的意义不仅仅在于查询省略object对象吧,如果一个对象关联其他好几个字典表,是不是需要在这个对象里面添加其他几个字典名称的冗余属性?反而用map就不需要
金贞花
金贞花
回复 @last : 他就没理解你的意思
last
last
回复 @xyxo : 不是所有的地方都用ORM的,你想想,你创建了几十个bean,仅仅只是用来映射查询结果,然后又不做其他任何的操作,这些对象创建出来有何作用?本来一个resultMap就足够了,没有必要再多此一举了吧.
xyxo
xyxo
回复 @last : 还是不太明白啊。 1)难道让Mybatis自动帮你创建一个HashMap来存放你的查询结果集就“眼不见心不烦”了吗? 2)你查询到的数据,不就是数据库中相对应的字段值?你在建ORM时,把这个object也省掉了吗?
last
last
在lz的项目里面完全不需要在写一个bean对象来映射一个个的查询结果集,因为这些数据结果只会用来做数据展示,没有其他用处,没必要为了这种需求来写出一堆的毫无用处的bean出来
0
淘淘我的小宝宝
淘淘我的小宝宝
就跟springmvc用map来做展示,不定义具体的业务bean,这样维护起来比较蛋疼,至少看页面模板文件比较蛋疼
CDD
CDD
回复 @last : 只是略微的蛋疼不会是很蛋疼的,即时request范围内存储的一个map对象,取值也是可以和bean对象一样的获取,如:${map.propName}
last
last
其实我们就是返回了个json串,所以是完全不需要bean的,需要看的时候直接去resultMap里面找,这个功能还是可以提供的-.-
0
_咫尺_
_咫尺_
写的不错,很有帮助,<setting name="callSettersOnNulls" value="true"/>好像需要mybatis3.2以上版本,实用的3.1.1启动就会出问题。
last
last
确实是要3.2+以上的版本,谢谢指出
0
0
leon_hn
leon_hn
用了mybatis-spring。。发现这并没有什么乱用,callSettersOnNulls没起作用
last
last
回复 @leon_hn : 也是可以的
leon_hn
leon_hn
回复 @last : 我自己继承mybatis-spring的sqlsessionfactorybean,给他加了个callSettersOnNulls属性,默认true,buildSqlSessionFactory的时候set到Configuration里边。。
last
last
如果没用的话,应该是已经被移除,或者你用的版本不支持,确定一下版本;要是实在不行的话就自定义TypeHandle
0
tangluyou
tangluyou

刚刚解决我的的问题,我用typehandler,谢谢谢谢

0
Ahoi762
Ahoi762

请问如果使用hibernate,这种情况怎么解决呢?

0
Ahoi762
Ahoi762

请问如果使用hibernate,这种情况怎么解决呢?@last

返回顶部
顶部