MyBatis 如何获取接口参数名?¶
一、背景¶
Mapper 接口:
XML:
<select id="selectBy" resultType="User">
SELECT * FROM user WHERE name = #{name} AND age = #{age}
</select>
为什么有的项目 #{name} 能用,有的项目必须写 #{arg0}?
二、ParamNameResolver 的工作¶
MyBatis 用 ParamNameResolver 解析参数。它的判断逻辑:
- 方法参数有
@Param:用注解的 value 作为 key。 - 没有
@Param,且编译保留了参数名(-parameters或 LocalVariableTable):用真实参数名。 - 都没有:用
arg0, arg1, ...或param1, param2, ...。
三、为什么 IDE 里好用、打 jar 后报错¶
- IDE(IDEA/Eclipse)默认编译带调试信息
-g,LocalVariableTable 里有真实参数名,MyBatis 3.4.1+ 可以读出来。 - Maven 默认
maven-compiler-plugin不一定带-parameters,打出来的 jar 就拿不到。
四、解决方案¶
方案 1:加 @Param(最稳)¶
方案 2:编译加 -parameters(JDK 8+)¶
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<parameters>true</parameters>
</configuration>
</plugin>
方案 3:MyBatis 配置¶
这个配置默认就是 true,但前提是 class 文件里真有参数名。
五、多参数默认命名规则¶
即使什么都不加,MyBatis 也会按以下方式命名:
但 arg0/arg1 在新版 MyBatis 中可能需要开 -parameters 才能用,param1/param2 永远可用。
六、单个参数的特殊情况¶
如果方法只有一个参数且没有 @Param,XML 中 #{xxx} 可以写任意名字(MyBatis 不校验):
User selectById(Long id);
<select id="selectById">
SELECT * FROM user WHERE id = #{whatever}
</select>
这是因为单参数不需要 key。
生产建议
团队规范:多参数一律加 @Param,避免"IDE 能跑、线上报错"的坑。