- 当通过servcie调用mapper接口的方法时,会调用代理对象MapperProxy的invoke 方法。然后会调用MapperMethod的invoke 方法。
- MapperMethod有两个成员,SqlCommand(mapper方法的全限定名,也就是MappedStatement的id)和MethodSignature(目标方法的返回类型,目标方法的参数列表信息)
MapperMethod的invoke 方法会调用MapperMethod的execute方法。
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
case SELECT:
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else if (method.returnsCursor()) {
result = executeForCursor(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
if (method.returnsOptional()
&& (result == null || !method.getReturnType().equals(result.getClass()))) {
result = Optional.ofNullable(result);
}
}
break;
case FLUSH:
result = sqlSession.flushStatements();
break;
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}
在执行查询前会调用 method.convertArgsToSqlCommandParam(args)方法,这就是处理方法参数的。
paramNameResolver.getNamedParams(args)方法
传入的是数组类型,转换成map
public Object getNamedParams(Object[] args) {
final int paramCount = names.size();
if (args == null || paramCount == 0) {
return null;
//没有@param注解并且参数只有一个
} else if (!hasParamAnnotation && paramCount == 1) {
Object value = args[names.firstKey()];
return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
} else {
//创建map
final Map<String, Object> param = new ParamMap<>();
int i = 0;
//name中保存的是参数名 args中是调用方法传入的值
//所以param的key就是参数名,value是参数实际传入值
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
//这里如果加了@param注解,这里也会进入 保存一个param1+value
if (!names.containsValue(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}
这里就是对参数名和参数值做一个映射,保存在map中,key是参数名,value是参数值,参数值就是调用getNamedParams方法时传入的,参数名是维护在paramNameResolver的names属性中,在paramNameResolver的构造方法中就已经获取到了方法的所有参数名及索引保存在了names中(查找@param注解),names也是map类型,key是参数的顺序,value是参数名称。
处理完参数继续查询方法,将处理完的参数传入