MyBatis-SpringBoot多表查询resultMap错误映射关联对象问题
MyBatis多表关联映射错位问题解决方案
问题根因
- 主结果集未显式配置
<id>标签:MyBatis做关联查询的结果合并时,依赖<id>标签标注的主键作为唯一标识区分不同行数据,当前仅配置了构造注入的idArg和普通<result>的pubId映射,没有用<id>标注主键,会导致结果合并逻辑混乱。 - 关联类型用错:业务中单个publication最多对应一个图片、视频、附件,属于一对一关联,使用
<collection>会按集合映射,本身不符合数据结构预期。 - 自动映射导致字段错配:MyBatis默认开启自动映射,当左连接返回的关联表字段全为null时,自动映射逻辑会从已查询到的所有字段中匹配关联对象的属性名,导致主表的pubId、pubTitle等值被错误赋值到关联对象的属性上。
- 没有配置关联对象空值校验:默认情况下MyBatis只要能找到匹配的属性就会实例化关联对象,不会判断关联外键是否为null。
修复步骤
1. 修正resultMap基础配置
给主结果集添加<id>标签,关闭自动映射避免字段错配:
<resultMap id="publication" type="PubModel" autoMapping="false"> <constructor> <idArg column="pubId" javaType="String"/> </constructor> <!-- 显式指定主键,用于MyBatis结果合并 --> <id property="pubId" column="pubId"/> <result property="pubTitle" column="pubTitle"/> <result property="pubBody" column="pubBody"/> <result property="pubDate" column="pubDate"/> <result property="pubAuthor" column="pubAuthor"/> <result property="articleType" column="articleType"/>
2. 替换collection为association,添加空值校验
使用<association>映射一对一关联,通过notNullColumn属性指定关联外键为null时不实例化关联对象:
<association property="thumbnail" javaType="SiteImage" notNullColumn="imageId"> <id property="imageId" column="imageId"/> <result property="imageUrl" column="imageUrl"/> </association> <association property="video" javaType="SiteVideo" notNullColumn="videoId"> <id property="videoId" column="videoId"/> <result property="videoUrl" column="videoUrl"/> </association> <association property="attachment" javaType="SiteAttachment" notNullColumn="attachmentId"> <id property="attachmentId" column="attachmentId"/> <result property="attachmentUrl" column="attachmentUrl"/> </association> </resultMap>
3. 修复SQL注入风险
将查询条件中的字符串拼接${pubId}替换为预编译占位符#{pubId}:
WHERE p.pubId = #{pubId}
修改完成后重启项目即可验证,外键为null时关联对象会直接返回null,不会再出现错配的实例化对象。
内容的提问来源于stack exchange,提问作者DabaCircle
相关产品推荐
相关产品推荐

