11.多个参数传递名称可变源码解读源码解读
//接口方法
public Dept selectDeptByIdAndName(@Param("id") int id , @Param("param2") String dName);
//xmlsql语句
<select id="selectDeptByIdAndName" resultType="dept" >
select
id,
dept_name,
dept_loc
from
t_dept
where
id = #{id}
and
dept_name = #{param2}
</select>
//测试方法
//查询多个普通参数
Dept dept = mapper.selectDeptByIdAndName(2, "研发部");
System.out.println("dept = " + dept);
//声名param字符串常量用于拼接param1,param2,...
private static final String GENERIC_NAME_PREFIX = "param";
//Map集合 nams中存放的是传入的参数名,这个参数名用户自己定义的
//在传入多个参数时,如果在方法上使用了@Param()注解声名了别名,则names中存放的就是别名,如果没有存放别名,则names中就是,默认固定的
//字符args0,...或者param1,... .这个字符是根据在sql语句中的#{args0}来识别的
private final SortedMap<Integer, String> names;
//判断是否使用了@Param注解,使用了则值为true ,没有使用则值为false
private boolean hasParamAnnotation;
public Object getNamedParams(Object[] args) {
//判断执行方法中传入了几个参数, paramCount = 2
int paramCount = this.names.size();
//判断有没有传入参数,没有则直接返回null
if (args != null && paramCount != 0) {
//如果没有使用@Param注解并且传入的参数个数只有一个则直接返回参数
if (!this.hasParamAnnotation && paramCount == 1) {
return args[(Integer)this.names.firstKey()];
} else {
//如果有多个参数,则声名一个Map集合用来存放参数
Map<String, Object> param = new ParamMap();
int i = 0;
//利用迭代器,遍历names中数据,即参入参数的名字 <Map>names[0 : "id",1 : "dName"]
for(Iterator var5 = this.names.entrySet().iterator(); var5.hasNext(); ++i) {
Entry<Integer, String> entry = (Entry)var5.next();
//args中存放的传入的形参数据,names中存放的是形参名:需要将args中的数据与names中的形参名一一对应
//entry.getValue() 取出的是id,(Integer)entry.getKey()取出是value对应的索引,就可以找到args对应的第几个参数和参数名一起存放到param中
param.put(entry.getValue(), args[(Integer)entry.getKey()]);
//拼接param[1,2..]
String genericParamName = "param" + String.valueOf(i + 1);
//如果没有则将paramN : names[N]的值加入map中
//如果有则不用添加
if (!this.names.containsValue(genericParamName)) {
param.put(genericParamName, args[(Integer)entry.getKey()]);
}
}
return param;
}
} else {
return null;
}
}
结论
1. 在接口定义方法时@Param注解要么所有参数都加上,要么所有参数都不要加
2. 在接口xml文件中使用占位符时,要么所有占位符都用别名,要么所有占位符都用默认值argsN或者paramN
3. 在底层map封装时会根据@param注解名称作为key,将参数数据作为value值进行封装.
4. 通常会将注解名对应的数据封装之后再用paramN值封装一次数据,即一般有两个参数map中会有4条数据,如果注解名和paramN值相同,这不会重复添加,这时可能只有三条数据,
5. 因此传入一条数据对应了两个不同的key值 ,所以在传参时使用别名和使用默认的paramN和argsN时都能识别