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

MyBatis批量插入生成ID遇问题:foreach内无法使用selectKey

解决MyBatis批量INSERT ALL时序列重复的问题

我完全懂你碰到的这个坑——用MyBatis写INSERT ALL做批量插入时,想给每一行生成唯一ID,但不管是在foreach里尝试用selectKey,还是调用外部的nextVal查询,结果所有行的ID都一模一样。这其实是MyBatis的预编译机制搞的鬼:当你把序列查询当成参数引用时,MyBatis只会执行一次这个查询,然后把结果重复填充到所有行里。

下面给你几个实用的解决方案:

方案1:直接在INSERT ALL的VALUES里调用序列

最省心的办法就是跳过MyBatis的参数绑定,直接在SQL里调用序列的nextVal,让数据库为每一行单独生成新的序列值。修改你的insertAll方法:

<insert id="insertAll" parameterType="list">
  INSERT ALL
  <foreach collection="items" item="item" separator="">
    INTO MY_TABLE (ID, COLUMN1, COLUMN2)
    VALUES (MY_SEQUENCE.nextVal, #{item.column1}, #{item.column2})
  </foreach>
  SELECT 1 FROM DUAL
</insert>

注意Oracle的INSERT ALL语法最后必须加SELECT 1 FROM DUAL来触发执行,这样每一行都会独立调用一次序列,保证ID唯一。

方案2:提前在Java代码中批量生成序列值

如果必须通过MyBatis获取序列值,可以先一次性查询出足够的序列值,分配给每个待插入对象后再执行批量插入:

  1. 先写一个批量获取序列的Mapper方法:
<select id="batchNextVal" resultType="java.lang.Long">
  SELECT MY_SEQUENCE.nextVal FROM DUAL
  CONNECT BY LEVEL <= #{count}
</select>

这个Oracle语法的SQL会一次性生成count个连续的序列值。

  1. 在业务代码中先拿序列值,再给每个对象赋值:
// list是你要插入的对象集合
List<Long> ids = mapper.batchNextVal(list.size());
for (int i = 0; i < list.size(); i++) {
  list.get(i).setId(ids.get(i));
}
mapper.insertAll(list);
  1. 最后修改insertAll的SQL,直接用对象里的ID:
<insert id="insertAll" parameterType="list">
  INSERT ALL
  <foreach collection="items" item="item" separator="">
    INTO MY_TABLE (ID, COLUMN1, COLUMN2)
    VALUES (#{item.id}, #{item.column1}, #{item.column2})
  </foreach>
  SELECT 1 FROM DUAL
</insert>

方案3:改用标准批量插入语法(foreach+INSERT INTO...VALUES)

如果你的Oracle版本是12c及以上,可以不用INSERT ALL,换成标准的批量插入写法,MyBatis能正确处理每个行的序列调用:

<insert id="insertAll" parameterType="list">
  INSERT INTO MY_TABLE (ID, COLUMN1, COLUMN2)
  VALUES
  <foreach collection="items" item="item" separator=",">
    (MY_SEQUENCE.nextVal, #{item.column1}, #{item.column2})
  </foreach>
</insert>

这种写法更简洁,而且每个VALUES组都会独立触发序列调用,不会出现重复ID的问题。

总结一下,最推荐方案1,直接在SQL里调用序列,简单高效,不需要额外的Java代码处理;如果有特殊业务限制,再考虑方案2或3。

内容的提问来源于stack exchange,提问作者Manuel Castro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:42:48