MapperMethod 中封装了Mapper 接口中对应方法的信息,以及对应SQL 语句的信息
MapperMethod 对象。MapperMethod 对象会完成参数转换以及SQL语句的执行功能
MapperMethod 中并不记录任何状态相关的信息,所以可以在多个代理对象之间共享
public class MapperMethod {
// 当前Mapper下Method的Sql信息(SqlCommand)
// SqlCommand包含SQL语句的名称和类型
private final SqlCommand command;
// 当前Mapper下Method的方法签名,包括入参与返回值(类型&位置信息等)
private final MethodSignature method;
public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, mapperInterface, method);
}
// 核心方法
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
// 根据SqlCommand的类型,执行不同的分支
switch (command.getType()) {
case INSERT: {
// 参数关联,将传入实参数与方法形参关联起来。通过MethodSIgnature下的convertArgsToSqlCommandParam(),间接调用ParamNameResolver.getNamedParams(),从而获取Map<paramterName, paramterValue>
Object param = method.convertArgsToSqlCommandParam(args);
// 通过sqlSession.insert(command.getName(), param)进行执行,并将其返回值(effectLines),按照当前Method的返回值,返回对应类型的值(int、long、boolean)
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:
// 根据返回值类型不同,调用不同执行方法,并返回不同结果
// 但其中executexxx()本质,还是调用sqlSession.xxx(),获取执行结果
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 {
// 这部分,个人认为也可以采用一个私有方法进行处理。
// 这里为什么不作为私有方法处理。个人猜测:一方面是命名(命名与语义关联);另一方面是为了更直观展示other的处理方式,提高代码可读性?
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;
}
小结:
MapperRegistry.getMapper -> MapperProxyFactory.newInstance -> MapperProxy.invoke -> MapperMethod.execute -> Sqlsession.xxx(进入执行时)
h.资源加载模块
(暂略)
i.日志模块
(暂略)
2.生命周期
a.初始化过程