You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MyBatis批量插入生成重复UUID主键问题求助

解决MyBatis批量插入时UUID主键重复的问题

这个问题我之前踩过一模一样的坑!核心原因是MyBatis在批量插入场景下,<selectKey>只会执行一次,而不是为集合中的每个元素单独生成UUID,导致所有插入记录共用同一个ID,自然就出现主键重复报错了。

下面给你几个亲测有效的解决方法,按需选择:

方法一:Java代码层提前生成UUID(最稳妥)

在调用MyBatis批量插入接口之前,手动为每个SysUser对象生成UUID并赋值。这种方式逻辑清晰,也能避免MyBatis批量处理特性带来的问题。

示例代码:

List<SysUser> userList = ...; // 待插入的用户列表
for (SysUser user : userList) {
    // 生成不带横线的UUID
    String uuid = UUID.randomUUID().toString().replace("-", "");
    user.setId(uuid);
}
// 调用批量插入方法
userMapper.batchAdd(userList);

对应的MyBatis批量插入XML配置(不需要<selectKey>):

<insert id="batchAdd" parameterType="java.util.List">
    insert into sys_user(id,user_name,user_email,user_info,user_password,create_time)
    values
    <foreach collection="list" item="user" separator=",">
        (#{user.id,jdbcType=VARCHAR}, 
         #{user.userName,jdbcType=VARCHAR}, 
         #{user.userEmail,jdbcType=VARCHAR}, 
         #{user.userInfo,jdbcType=VARCHAR}, 
         #{user.userPassword,jdbcType=VARCHAR}, 
         #{user.createTime,jdbcType=TIMESTAMP})
    </foreach>
</insert>

方法二:在批量插入SQL中直接生成UUID(数据库层处理)

如果不想在代码层处理,可以直接在批量插入的SQL语句中,为每条记录调用数据库的UUID生成函数,这样每条插入都会生成独立的UUID。

示例XML配置:

<insert id="batchAdd" parameterType="java.util.List">
    insert into sys_user(id,user_name,user_email,user_info,user_password,create_time)
    values
    <foreach collection="list" item="user" separator=",">
        (replace(uuid(),'-',''), 
         #{user.userName,jdbcType=VARCHAR}, 
         #{user.userEmail,jdbcType=VARCHAR}, 
         #{user.userInfo,jdbcType=VARCHAR}, 
         #{user.userPassword,jdbcType=VARCHAR}, 
         #{user.createTime,jdbcType=TIMESTAMP})
    </foreach>
</insert>

这种方式的好处是不需要修改Java代码,完全由数据库负责ID生成,但要注意不同数据库的UUID函数可能有差异(比如MySQL用UUID(),Oracle也是UUID()但格式细节可能不同,需要根据你的数据库调整)。

为什么单条插入没问题?

单条插入时,MyBatis会在执行insert语句前,单独执行一次<selectKey>中的SQL,生成UUID并赋值给SysUser对象的id属性,所以不会重复。但批量插入时,MyBatis默认只会执行一次<selectKey>,导致所有元素共用同一个ID,这就是问题的根源。

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

火山引擎 最新活动