查询结果被合并
mapper 中定义的 sql 查询结果有3条,但执行 mapper 接口方法返回的实体列表只有1条,数据数量不符。这有可能是由于 xml 中的定义的 resultMap
有缺陷,如没有明确的定义一个用作主键的列,这分两种情况分别说明。
// reusltMap 定义
<resultMap id="vo" type="ProjectCentersStatisticsVo">
<association property="entityA" javaType ="domain.entityA">
<id property="id" column="id" />
</association>
</resultMap>
<select id="selectSql" resultMap="vo">
select id, name from t where xxx
</select>
第一种,resultMap
的定义中没有任何 result
或列,有的是 association
或collection
,association
中有id
定义,此时,不会出现该问题,sql语句中出现的唯一的id
被映射到entityA
中的id
;
第二种,resultMap
中定义了一个result
,但它并不是id或者它在sql查询结果中并不是唯一的,但此时mybatis会将其看作主键来使用,值相同的结果被合并留下最后一条,会造成问题发生。
<resultMap id="vo" type="ProjectCentersStatisticsVo">
<result property="name" column="name" />
<association property="entityA" javaType ="domain.entityA">
<id property="id" column="id" />
</association>
</resultMap>
在上例中,resultMap
中定义了一个name
列,mybatis在处理查询结果时会将其作为主键,name
相同的记录(行)将替代上一个,直至留下最后一个name
不同的行。例如查询结果有3条,其中两条name
是tom
,一条name
是jerry
,mybatis处理后将返回2条记录,最后一条tom
和唯一的一条jerry
。
第三种,为了避免发生上述问题,人为明确的定义一个主键在resultMap
中,默认名字是id
,如下
<resultMap id="vo" type="ProjectCentersStatisticsVo">
<result property="pk" column="pk" />
<result property="name" column="name" />
<association property="entityA" javaType ="domain.entityA">
<id property="id" column="id" />
</association>
</resultMap>
<select id="selectSql" resultMap="vo">
select id, id pk, name from t where xxx
</select>
在上例中,通过给resultMap
增加一个pk
字段来表示主键,在sql
中增加一个pk
列并为了保证其值的唯一用真的id填充,这样的好处是原本查询结果中的id
字段还能正确映射到entityA
中的id