使用MyBatis框架时Mapper传参是否需要使用@Param注解
在使用MyBatis作为Java项目的ORM框架时,在Mapper接口中传递参数需要通过@Param
注解指定参数名称,这样才能在Mapper接口对应的xml文件中引用到对应名称的参数。如果不在Mapper接口中明确使用@Param
注解时将会报错:找不到指定名称的参数
。
追根溯源,这要从MyBatis获取Mapper接口参数名的实现说起,如下源码:
// ParamNameResolver.java
// 在ParamNameResolver构造函数中获取Mapper接口参数的实现思路如下:
// 1.如果参数使用注解@Param,则取注解值作为参数名;
// 2.如果参数未使用注解@Param,就尝试通过反射方式获取Mapper接口的参数名;
// 3.如果在第2步仍然未获取到参数名,则使用参数索引值(如:0,1,2....)作为参数名;
public ParamNameResolver(Configuration config, Method method) {
this.useActualParamName = config.isUseActualParamName();
final Class<?>[] paramTypes = method.getParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final SortedMap<Integer, String> map = new TreeMap<>();
int paramCount = paramAnnotations.length;
// get names from @Param annotations
for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
if (isSpecialParameter(paramTypes[paramIndex])) {
// skip special parameters
continue;
}
String name = null;
for (Annotation annotation : paramAnnotations[paramIndex]) {
if (annotation instanceof Param) {
hasParamAnnotation = true;
name = ((Param) annotation).value();
break;
}
}
if (name == null) {
// @Param was not specified.
if (useActualParamName) {
name = getActualParamName(method, paramIndex);
}
if (name == null) {
// use the parameter index as the name ("0", "1", ...)
// gcode issue #71
name = String.valueOf(map.size());
}
}
map.put(paramIndex, name);
}
names = Collections.unmodifiableSortedMap(map);
}
// 通过注解方式获取Mapper参数名
private String getActualParamName(Method method, int paramIndex) {
return ParamNameUtil.getParamNames(method).get(paramIndex);
}
// ParamNameUtil.java
public class ParamNameUtil {
public static List<String> getParamNames(Method method) {
return getParameterNames(method);
}
public static List<String> getParamNames(Constructor<?> constructor) {
return getParameterNames(constructor);
}
// 这里依赖Java编译器在编译代码时是否保留了参数的实际名称,如果未保留参数实际名称则返回null
private static List<String> getParameterNames(Executable executable) {
return Arrays.stream(executable.getParameters()).map(Parameter::getName).collect(Collectors.toList());
}
private ParamNameUtil() {
super();
}
}
综上所述,在MyBatis框架的Mapper接口中是否需要使用注解@Param
明确指定参数名称,依赖Java编译器在编译代码时是否保留了方法参数的实际名称。
那么问题就转变成了:Java编译器在什么时候会保留方法参数的实际名称呢?依赖2个条件:
1.JDK版本必须是8及以上,参见:java8中新增编译参数parameters入门,jdk1.8 开启-parameters参数,编译保留参数名,为反射提供便利。
2.在Maven插件maven-compiler-plugin
中明确设置编译参数,根据插件版本不同,设置编译参数的方式各异,如下:
- 版本3.6.2之前
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<!-- 添加编译JDK8+支持的编译参数-parameters,保留方法参数名称 -->
<compilerArgs>-parameters</compilerArgs>
</configuration>
</plugin>
- 版本3.6.2及之后
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<!-- 添加编译JDK8+支持的编译参数-parameters,保留方法参数名称 -->
<parameters>true</parameters>
</configuration>
</plugin>
当然,在IDEA中运行代码时,如果没有明确配置maven-compiler-plugin
插件的编译参数,还可以设置项目模块的编译参数,如下:
【参考】
MyBatis多参数传递之@Param究竟加还是不加?
关于Mybatis的@Param注解
Mybatis省略@Param注解原理
作者:编程随笔
出处:http://www.cnblogs.com/nuccch/
声明:本文版权归作者和博客园共有,欢迎转载,但请在文章页面明显位置给出原文连接。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)