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

MyBatis注解式IN列表更新报错:无法找到参数uuid

问题解决:MyBatis批量扣减用户金币时参数绑定异常

问题描述

需求为批量将指定UUID列表中用户的金币减少指定数额,使用MyBatis Kotlin注解编写的DAO方法执行时抛出绑定异常,报错信息翻译如下:

07:59:14.340 DEBUG c.s.g.d.d.U.reduceUsersGold - ==> 准备执行: UPDATE users SET gold = gold - ? gold >= ? AND uuid IN ?

更新数据库出错。原因: org.apache.ibatis.binding.BindingException: 未找到参数'uuid'。可用参数为 [amount, param1, uuids, param2]

错误可能存在于 com/simple/games/data/dao/UserDao.java (最佳猜测)

错误可能涉及 com.simple.games.data.dao.UserDao.reduceUsersGold-Inline

错误发生在设置参数时

SQL: UPDATE users SET gold = gold - ? gold >= ? AND uuid IN ?

原因: org.apache.ibatis.binding.BindingException: 未找到参数'uuid'。可用参数为 [amount, param1, uuids, param2]

根因分析

MyBatis注解方式的SQL中,包含<foreach>、<where>这类动态SQL标签的语句必须用<script>标签包裹,否则MyBatis不会解析这些动态标签,会将其当作普通SQL文本处理。此处<foreach>未被解析,导致内部的#{uuid}被误认为是独立的方法参数,但实际方法中并没有该参数,因此抛出绑定异常。

修复方案

在@Update注解的SQL外层添加<script>标签,让MyBatis正确解析动态SQL:

@Update(
    """
    <script>
        UPDATE users
        SET gold = gold - #{amount}
        <where>
            gold >= #{amount}
            AND uuid IN 
            <foreach 
                collection="uuids" item="uuid" open="(" separator="," close=")" > #{uuid}
            </foreach>
        </where>
    </script>
"""
)
fun reduceUsersGold(
    @Param("uuids") uuids: List<String>,
    @Param("amount") amount: Int,
): Int

验证说明

修复后,MyBatis会正确解析<foreach>标签,遍历传入的uuids列表生成对应IN子句,#{uuid}会被识别为循环的当前项而非独立参数,避免绑定异常。同时<where>标签会自动处理多余的AND/OR条件,保证SQL语法正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:55:54