首页 > 解决方案 > MyBatis - SpringBoot 将结果映射到错误的对象

问题描述

我正在尝试进行多表选择。下面是我的 mapper.xml:

<select id="getPublicationById"
        resultMap="publication"
        parameterType="string" useCache="false">
    SELECT p.pubId,
           p.pubTitle,
           p.pubBody,
           p.pubDate,
           p.pubAuthor,
           p.articleType,
           si.imageId as imageId, # imageId is a foreign key referenced in p
           si.imageUrl as imageUrl,
           sv.videoId as videoId, # videoId is a foreign key referenced in p
           sv.videoUrl as videoUrl,
           sa.attachmentId as attachmentId, # attachmentId is a foreign key reference in p
           sa.attachmentUrl as attachmentUrl
    FROM publication p
             LEFT JOIN site_image si ON p.thumbnailId = si.imageId
             LEFT JOIN site_attachment sa on p.attachmentId = sa.attachmentId
             LEFT JOIN site_video sv on p.videoId = sv.videoId
    WHERE p.pubId = '${pubId}'
</select>

<resultMap id="publication"
           type="PubModel">
    <constructor>
        <idArg column="pubId" javaType="String"/>
    </constructor>
    <result 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"/>
    <collection property="thumbnail" ofType="SiteImage">
        <id property="imageId" column="imageId"/>
        <result property="imageUrl" column="imageUrl"/>
    </collection>
    <collection property="video" ofType="SiteVideo">
        <id property="videoId" column="videoId"/>
        <result property="videoUrl" column="videoUrl"/>
    </collection>
    <collection property="attachment" ofType="SiteAttachment">
        <id property="attachmentId" column="attachmentId"/>
        <result property="attachmentUrl" column="attachmentUrl"/>
    </collection>

</resultMap>

我正在查询的特定行对于videoIdand具有空外键attachmentId,因此,我期望返回的SiteVideoSiteAttachment对象为空。

然而,看起来 MyBatis 将不相关的结果分配给这两个对象:

PubModel(pubId=spongebob101, pubTitle=spongebob, pubBody=haha, pubDate=2021-08-30T15:10:38, pubAuthor=Wang Cai, articleType=MARKDOWN, thumbnail=[SiteImage(imageId=1, imageUrl=google.com)], video=[SiteVideo(videoId=spongebob101, videoUrl=spongebob)], attachment=[SiteAttachment(attachmentId=spongebob101, attachmentUrl=spongebob)])

如您所见,分配给这两个对象的字段实际上是结果,pubId并且pubTitle不是预期的。这里发生了什么?

我尝试了其他方法,例如使用关联而不是收集,并且不使用这两种方法。但没有任何效果。

标签: spring-bootmybatisspring-mybatis

解决方案


在阅读了相关的 PR后,我找到了解决问题的方法。我将全参数构造函数添加到我的 POJO 中,Java 自动摆脱了无参数构造函数。看起来当无参数构造函数不存在时,MyBatis 会自动切换到构造函数自动映射。构造函数自动映射依赖于返回结果的列顺序,MyBatis 只需要调用我的 POJO 的全参数构造函数,并得到一些非空结果。

解决方案是手动添加另一个无参数构造函数,然后 MyBatis 不再使用构造函数自动映射。


推荐阅读