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
相关产品推荐
相关产品推荐

