2025 年把一个 Gradle 管理的 Spring Boot 项目从 IDEA 切换到 Cursor 开发时,应用已经能启动,但部分接口请求报错:

Parameter '0' not found.
Available parameters are [arg1, arg0, param1, param2]

同一套代码在 IDEA 下正常,问题集中在没有标注参数名的多参数 Mapper 方法。

先对齐 Mapper 与 SQL 的名字

MyBatis 需要把 SQL 占位符与方法参数对应起来。多参数方法可以显式指定名字:

import org.apache.ibatis.annotations.Param;

int countByState(
    @Param("state") String state,
    @Param("kind") String kind
);
<select id="countByState" resultType="int">
  SELECT COUNT(*) FROM items
  WHERE state = #{state} AND kind = #{kind}
</select>

例子只展示映射关系,表名与字段需与自己的模型对应。不能把报错中的数字、arg0 或 param1 任意替换后就认为契约已经清楚;应检查实际 SQL 引用了什么名字。

依赖源码参数名时,需要编译信息

Java 的 -parameters 可以把正式参数名写入 class 文件;MyBatis 的 useActualParamName 设置还决定是否使用这些名字。仅有 Java 8 或更高版本并不自动保证参数名被保留。MyBatis 设置说明

使用 Gradle JavaCompile 的项目,可以把编译选项落到构建脚本。下面是 Groovy DSL 示例:

tasks.withType(JavaCompile).configureEach {
    options.compilerArgs.add('-parameters')
}

它配置的是 Gradle 的编译任务,不会自动控制一个绕过 Gradle、独立编译代码的编辑器服务。需要同时确认实际构建入口。Gradle CompileOptions

为什么换编辑器后才暴露

当年的处理是在 Cursor 的 Java 编译设置中开启保留参数名,重新启动后错误消失。这说明应重视编译配置差异,但不能由此推断所有 Cursor 或 IDEA 版本的默认行为。

排查时记录实际使用的 JDK、编译任务和运行 class 来源,按正常构建流程重新编译,避免读到旧产物。对于多参数 Mapper,显式 @Param 通常更直观;如果依赖参数名元数据,应让命令行、CI 和 IDE 的构建规则一致。