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

MyBatis Mapper查询返回结果重复问题排查:数据库仅两条数据却返回四条结果

为什么MyBatis查询返回重复的结果?

这个问题很典型,我来帮你拆解一下原因和解决方案:

问题根源:SQL逻辑错误导致重复输出

先看你写的Mapper SQL代码:

<select id="selectList" resultType="map" >
    <foreach collection="list" item="items" separator=" union all ">
        SELECT #{items.id,jdbcType=INTEGER} id, #{items.name,jdbcType=VARCHAR} name FROM category
    </foreach>
</select>

这段代码的实际执行逻辑是:

  • 对于你传入的List里的每一个元素(也就是map1和map2),都会执行一次查询
  • 每次查询都会取出category表中的所有行,然后把每行的id替换成你传入的items.id,name替换成你传入的items.name
  • 最后用union all把两次查询的结果合并

因为你的category表本身有2条数据,所以第一次循环(对应map1的id=1、name=haha)会返回2条完全一样的{id=1, name=haha};第二次循环(对应map2的id=2、name=update)又返回2条完全一样的{id=2, name=update}。加起来就是2+2=4条结果,这就是你看到重复的原因。

针对不同需求的解决方案

需求1:查询category表中与传入id匹配的真实数据

如果你是想根据传入的id列表,获取category表中对应的真实记录,应该修改SQL为带条件的查询:

<!-- 用union all的写法 -->
<select id="selectList" resultType="map" >
    <foreach collection="list" item="items" separator=" union all ">
        SELECT id, name FROM category WHERE id = #{items.id,jdbcType=INTEGER}
    </foreach>
</select>

或者更高效的IN子句写法(推荐,减少SQL拼接次数):

<select id="selectList" resultType="map" >
    SELECT id, name FROM category 
    WHERE id IN 
    <foreach collection="list" item="items" open="(" separator="," close=")">
        #{items.id,jdbcType=INTEGER}
    </foreach>
</select>

需求2:直接返回传入的id和name数据(不需要查询表)

如果你本来就只是想输出你传入的那两组数据,根本不需要关联category表,那去掉FROM category即可(MySQL可以直接省略FROM,Oracle需要用FROM dual):

<select id="selectList" resultType="map" >
    <foreach collection="list" item="items" separator=" union all ">
        SELECT #{items.id,jdbcType=INTEGER} id, #{items.name,jdbcType=VARCHAR} name
    </foreach>
</select>

总结

核心问题是你原SQL中每个foreach循环都全表扫描了category,把表中每一行都用传入参数替换字段值后再合并,自然产生了重复结果。根据你的实际业务需求调整SQL逻辑就能解决问题啦。

内容的提问来源于stack exchange,提问作者鹰 9am

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:27:37