通过本篇文章我们聊一下一次SQL执行的步骤都有哪些
总体执行图,本篇文章的核心

部分核心代码分析
demo
1 | SqlSession session = sqlSessionFactory.openSession(); |
session.getMapper 获取到MapperProxy
就是上文中的ArticleDao articleDao = session.getMapper(ArticleDao.class);
因为Mapper是接口不能直接实例化,所以MapperProxy就是使用JDK动态代理功能,间接实例化Mapper。
使用MapperProxy.invoker方法-> 获取到MapperMethod
demo中的articleDao.findOne(1);
就是调用mapperProxy.invoker方法
这部分功能就是,从SqlSession->Executor过程
部分源码
1 | @Override |
MapperMethod
MapperMethod 代码结构图

可以看出来实际上就是只有两个public
的方法,一个是构造函数,一个就是execute.
所有就是有两个功能
- 解析Mapper接口方法,封装成MapperMethod对象。这里要注意下,有两个类成员
SqlCommand
,这个类包含了执行的方法是属于那种类型。MethodSignature
执行方法的一些属性,返回值的类型(单个,还是批量,还是其他)
- 将
SqlCommand
路由到SqlSession对应的方法上MapperMethod.execute
根据入参,路由到SqlSession提供的方法中.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45public 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);
}
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;
}
在之后就是SqlSession->Executor->StatementHandler 这条链路了。我会在其他的文章中详解