源码分析这里不好描述可以直接观看视频http://www.gulixueyuan.com/course/43/task/1172/show(需要注册)
下面简单的介绍下
背景:
dao中如下方式传入参数时public Employee getEmp(@Param("id")Integer id,String lastName); 映射文件用取值:id==>#{id/param1} lastName==>#{param2}
那么映射文件在使用时为什么会有param1,param2这个两个key的名称呢?
代理对象方法如下
所以重点是上图中的36行代码
经过简单的跟踪到这个公共的方法会看到,mybatis处理参数的核心代码如下(下面的代码中的注释是自己手动添加的原mybatis的jar包中是没有的)
public Object getNamedParams(Object[] args) {
final int paramCount = names.size();
//1、参数为null直接返回
if (args == null || paramCount == 0) {
return null;
//2、如果只有一个元素,并且没有Param注解;args[0]:单个参数直接返回
} else if (!hasParamAnnotation && paramCount == 1) {
return args[names.firstKey()];
//3、多个元素或者有Param标注
} else {
final Map<String, Object> param = new ParamMap<Object>();
int i = 0;
//4、遍历names集合;{0=id, 1=lastName,2=2}
for (Map.Entry<Integer, String> entry : names.entrySet()) {
//names集合的value作为key; names集合的key又作为取值的参考args[0]:args【1,"Tom"】:
//eg:{id=args[0]:1,lastName=args[1]:Tom,2=args[2]}
param.put(entry.getValue(), args[entry.getKey()]);
// add generic param names (param1, param2, ...)param
//额外的将每一个参数也保存到map中,使用新的key:param1...paramN
//效果:有Param注解可以#{指定的key},或者#{param1}
final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
// ensure not to overwrite parameter named with @Param
if (!names.containsValue(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}
}