You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis使用collection标签查询时如何保留重复数据

MyBatis结果映射重复数据保留方案

问题根因

MyBatis结果映射默认通过唯一标识区分不同记录:如果显式配置了<id>标签就用该标签值作为唯一标识,未配置时会把所有<result>字段的组合值作为唯一标识,相同标识的记录会自动合并去重。你当前的配置没有指定唯一标识,且使用<collection>映射字段时,相同值的元素会被自动合并。

解决方案

方案1:给ResultMap添加唯一ID标识(最推荐)

在结果映射顶层添加对应查询结果唯一列的<id>标签,比如数据库主键、临时行号等,示例配置如下:

<resultMap id="自定义resultMapId" type="你的实体类全限定名">
  <!-- 新增id标签,column对应查询结果唯一列名,property对应实体类字段名 -->
  <id column="id" property="id" jdbcType="BIGINT"/>
  <!-- 原有collection配置保持不变 -->
  <collection property="studentName" ofType="java.lang.String">
    <result column="student_name"/>
  </collection>
  <collection property="studentClass" ofType="java.lang.String">
    <result column="student_class"/>
  </collection>
  <collection property="studentGrade" ofType="java.lang.String">
    <result column="student_grade"/>
  </collection>
</resultMap>

如果查询结果没有原生唯一列,可以在SQL语句中用ROW_NUMBER() OVER() AS row_id生成临时唯一行号,将row_id映射为<id>即可。

方案2:调整映射标签(适用单值字段场景)

如果你要映射的是每行对应单个学生姓名、班级、年级的单值场景,属于标签使用错误,<collection>是用来映射一对多的集合属性的,直接替换为普通<result>标签即可完全避免去重问题:

<resultMap id="自定义resultMapId" type="你的实体类全限定名">
  <result property="studentName" column="student_name" jdbcType="VARCHAR"/>
  <result property="studentClass" column="student_class" jdbcType="VARCHAR"/>
  <result property="studentGrade" column="student_grade" jdbcType="VARCHAR"/>
</resultMap>

方案3:绕过结果缓存去重逻辑

如果确实需要保留集合内的所有重复元素,可直接在对应<select>查询标签上添加resultSetType="FORWARD_ONLY"属性,绕过MyBatis的结果缓存去重逻辑:

<select id="你的Mapper接口方法名" resultMap="自定义resultMapId" resultSetType="FORWARD_ONLY">
  你的查询SQL语句
</select>

内容的提问来源于stack exchange,提问作者Duelist Grand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:39:02