是通过MapperMethod来处理的,根据接口及方法名解析得到SqlCommand及MethodSignature,其主要是通过MethodSignature来解析请求参数的。
解析mapper接口参数
通过ParamNameResolver来得到参数下标到参数名之间的映射。处理过程
1、过滤掉RowBounds、ResultHandler类型参数
2、参数有使用@Param注解时,使用注解名来表示参数名,没有时
(1)全局配置时使用实际的参数名,则通过ParamNameUtil得到实现的参数名
(2)否则使用参数索引来表示参数名,例如"0", "1",...
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);
}
传参转成sql参数
1、如果参数个数只有一个,并且没有@Param注解,使用wrapToMapIfCollection转换,后序处理与没有使用mapper时一样。
2、否则将参数名与参数值添加到ParamMap中,同时会将param+参数索引,与参数值添加到ParamMap中
public Object getNamedParams(Object[] args) {
final int paramCount = names.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasParamAnnotation && paramCount == 1) {
Object value = args[names.firstKey()];
return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
} else {
final Map<String, Object> param = new ParamMap<>();
int i = 0;
for (Map.Entry<Integer, String> entry : names.entrySet()) {
param.put(entry.getValue(), args[entry.getKey()]);
// add generic param names (param1, param2, ...)
final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
// ensure not to overwrite parameter named with @Param
if (!names.containsValue(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}