MyBatis association嵌套collection带columnPrefix时映射错误如何解决
问题根源
MyBatis 嵌套映射的columnPrefix会逐层叠加生效,同时嵌套集合映射依赖各层resultMap的主键声明做结果分组聚合,你目前的配置缺少外层ResultMap的主键声明,导致MyBatis无法正确识别相同父对象的多条关联记录,最终集合仅保留最后一条或0条记录。
1 补全各层ResultMap的主键声明
- 最外层
PreMigrationData对应的resultMap需要显式声明主键,用于识别唯一的父对象实例 - Route对应的resultMap也需要声明主键,避免MyBatis无法区分不同的Route记录
修改后的ResultMap配置如下:
<resultMap id="resultMap" type="***.PreMigrationData" autoMapping="true"> <!-- 外层主键对应TmpCase的唯一标识sid,列名需带上association的i_前缀 --> <id column="i_sid" property="tmpCase.sid"/> <association property="tmpCase" javaType="***.TmpCase" columnPrefix="i_"> <id column="sid" property="sid"/> <result column="pid" property="pid"/> <collection property="routes" ofType="***.Route" resultMap="routes" columnPrefix="rt_"/> </association> </resultMap> <resultMap id="routes" type="***.Route"> <!-- 补全Route表的主键声明 --> <id column="sid" property="sid"/> <result column="pid" property="pid"/> ... </resultMap>
2 校验SQL列名与拼写
- 检查你SQL片段的引用拼写:你当前配置的
<include refid="rotue">大概率是拼写错误,正确应该为<include refid="route">,拼写错误会导致Route相关字段没有查询,自然映射为空 - 确认SQL执行后返回的Route字段前缀为
i_rt_,例如Route的sid列别名为i_rt_sid,符合association的i_前缀+collection的rt_前缀的叠加规则,MyBatis会逐层去掉前缀匹配字段
3 优化查询配置
在select标签上添加resultOrdered="true"配置,告诉MyBatis查询结果已经按父对象主键排序,提升集合聚合的效率和准确性:
<select id="getCases" resultMap="resultMap" resultOrdered="true"> <include refid="select"/> WHERE ... </select>
内容的提问来源于stack exchange,提问作者Vasiliy Pupkov
相关产品推荐
相关产品推荐

