MyBatisSQL参数占位符与全局属性useActualParamName详细介绍与原理剖析
作者:互联网
这个世界并不缺Java工程师,缺的是有“内涵”的工程师
从本质看,Mybatis其实是 SQL 语句与数据做映射作用的框架,是一个映射器。在查询数据的时候,SQL 语句的参数占位符起着至关重要的作用。
与参数占位符映射的配置中有一个全局变量useActualParamName。
关于useActualParamName参数的解释:允许使用方法签名中的名称作为语句参数名称。
mybatis.configuration.use-actual-param-name=true(默认是true)
在研究参数占位符书写规则的时候,有几个代码块至关重要。
package org.apache.ibatis.reflection
//ParamNameResolver类的构造函数,主要作用是初始化参数
//得到一个Map<Integer, String>(key=参数索引,value=参数名称),方便后面参数映射
public ParamNameResolver(Configuration config, Method method) {
//获取参数类型
final Class<?>[] paramTypes = method.getParameterTypes();
//获取参数注解
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final SortedMap<Integer, String> map = new TreeMap<Integer, String>();
//参数长度
int paramCount = paramAnnotations.length;
// 遍历每一个参数
for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
//如果为特殊参数(RowBounds(分页对象) 和 ResultHandler(结果处理)),则不会记入mapper的实际参数
if (isSpecialParameter(paramTypes[paramIndex])) {
// skip special parameters
continue;
}
String name = null;
//判断参数是否由@Param注解修饰
for (Annotation annotation : paramAnnotations[paramIndex]) {
if (annotation instanceof Param) {
hasParamAnnotation = true;
name = ((Param) annotation).value();
break;
}
}
if (name == null) {
// @Param was not specified.
if (config.isUseActualParamName()) {
//如果配置了useActualParamName=true的话,则取实际参数的名称
name = getActualParamName(method, paramIndex);
}
if (name == null) {
//否则,该参数的名称为0,1....n
name = String.valueOf(map.size());
}
}
map.put(paramIndex, name);
}
names = Collections.unmodifiableSortedMap(map);
}
//此接口的作用:获取参数对象集合:
//map<String,Object>(key=参数名,value=参数值) | 实际的对象(只有一个参数 & 没有参数注解)
public Object getNamedParams(Object[] args) {
final int paramCount = names.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasParamAnnotation && paramCount == 1) {
//只有一个参数 & 没有参数注解,直接返回值
return args[names.firstKey()];
} else {
final Map<String, Object> param = new ParamMap<Object>();
int i = 0;
for (Map.Entry<Integer, String> entry : names.entrySet()) {
//保存key为参数名,value为参数值的集合数据
param.put(entry.getValue(), args[entry.getKey()]);
// add generic param names (param1, param2, ...)
final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
// ensure not to overwrite parameter named with @Param
if (!names.containsValue(genericParamName)) {
//保存key为param0-paramn规则的字符串,value为参数值的集合对象
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}
测试:
mybatis.configuration.use-actual-param-name=false
public interface DemoMapper {
@Select("select username from user where id=#{id}")
//不加@Param参数
//mybatis.configuration.use-actual-param-name=false
String getUserById(int id);
}
进入单参数处理程序,查询成功!
public interface DemoMapper {
@Select("select username from user where id=#{id}")
@Select("select username from user where id=#{param1}")
//加上@Param参数
//mybatis.configuration.use-actual-param-name=false
String getUserById(@Param("id") int id);
}
进入多参数处理程序,key为占位符,value为参数值,使用对应占位符(key)都可以查询成功!
public interface DemoMapper {
@Select("select username from user where id=#{0} and sex=#{param2}")
@Select("select username from user where id=#{0} and sex=#{1}")
//不加@Param参数
//mybatis.configuration.use-actual-param-name=false
String getUserById(int id,int sex);
}
进入多参数处理程序,key为占位符,value为参数值,使用对应占位符(key)都可以查询成功!
public interface DemoMapper {
@Select("select username from user where id=#{id} and sex=#{sex}")
@Select("select username from user where id=#{param1} and sex=#{sex}")
//加上@Param参数
//mybatis.configuration.use-actual-param-name=false
String getUserById(@Param("id") int id,@Param("sex") int sex);
}
进入多参数处理程序,key为占位符,value为参数值,使用对应占位符(key)都可以查询成功!
mybatis.configuration.use-actual-param-name=true
public interface DemoMapper {
@Select("select username from user where id=#{id}")
//不加@Param参数
//mybatis.configuration.use-actual-param-name=true
String getUserById(int id);
}
进入单参数处理程序,查询成功!
public interface DemoMapper {
@Select("select username from user where id=#{id}")
@Select("select username from user where id=#{param1}")
//加上@Param参数
//mybatis.configuration.use-actual-param-name=true
String getUserById(@Param("id") int id);
}
进入多参数处理程序,key为占位符,value为参数值,使用对应占位符(key)都可以查询成功!
```java
public interface DemoMapper {
@Select("select username from user where id=#{id} and sex=#{sex}")
@Select("select username from user where id=#{param1} and sex=#{sex}")
//不加@Param参数
//mybatis.configuration.use-actual-param-name=true
String getUserById(int id,int sex);
}
进入多参数处理程序,key为占位符,value为参数值,使用对应占位符(key)都可以查询成功!
public interface DemoMapper {
@Select("select username from user where id=#{id} and sex=#{sex}")
@Select("select username from user where id=#{param1} and sex=#{sex}")
//加上@Param参数
//mybatis.configuration.use-actual-param-name=true
String getUserById(int id,int sex);
}
进入多参数处理程序,key为占位符,value为参数值,使用对应占位符(key)都可以查询成功!
总结:
单参数:
不加注解@Param:参数use-actual-param-name不影响占位符,填什么都可以
加注解@Param:参数use-actual-param-name不影响占位符,但是只能填参数名或者param1-n格式的占位符
多参数:
只有参数use-actual-param-name为false,且不加注解@param这种情况占位符需要填0-n或者param1-n格式的占位符
其他情况填参数名或者param1-n格式的占位符
bilibili账号:段某人
文章持续更新,可以微信扫码关注第一时间阅读
标签:name,useActualParamName,param,占位,参数,Param,MyBatisSQL,id,符与 来源: https://blog.csdn.net/qq_15038565/article/details/115414387