【Spring源码】SpringBoot_MyBatis_starter源码(二)
SqlSession
好了,继上一节的 SqlSession 继续,一气呵成。
1 | private class SqlSessionInterceptor implements InvocationHandler { |
OK,来到 DefaultSqlSession#selectOne:
1 |
|
看得到,有对象封装的情况下,无论查询一个还是多个,都是使用 List 来接收。
1 |
|

应该不难理解他是干嘛的,就是存储 SQL 的执行情况。
Executor执行查询
官网上是这么写的:
ExecutorType.SIMPLE:这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。 ExecutorType.REUSE:这个执行器类型会复用预处理语句。 ExecutorType.BATCH:这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行,必要时请把它们区分开来以保证行为的易读性。
那现在默认是启用 Cache 的(装配的时候,注入了 CachingExecutor,他可以说是个装饰类,装饰了 SimpleExecutor,必要的时候缓存数据):
1 | public class CachingExecutor implements Executor { |
BoundSql 可以说是一个执行 jdbc 所需要数据的最小子集,剥离了 MyBatis 的配置,那下一步就是一个 CacheKey,我们来看看怎么获取 CacheKey 的:
1 |
|
再看 query 方法:
1 |
|
1 | // BaseExecutor |
queryFromDatabase 函数:
1 | private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { |
准备Statement
1 |
|
那 StatementHandler 类型的 RoutingStatementHandler 是做什么用的,就是指路用什么方式来实现 jdbc 的调用:
1 | public class RoutingStatementHandler implements StatementHandler { |
那上面拿到了 StatementHandler 以后就是准备跟 Connection 连接在一起了 stmt = prepareStatement(handler, ms.getStatementLog()):
1 | private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException { |
参数处理器
也是一样交给了 PreparedStatementHandler 来处理:
1 |
|
使用 ParameterHandler 来处理参数,ParameterHandler 是在装配的时候,根据 mapper.xml 来注入参数处理器,像我们使用 xml 就是被装配了个默认的参数处理器(DefaultParameterHandler)。
1 | public class DefaultParameterHandler implements ParameterHandler { |
类型解析并处理
首先使用了一个 UnknownTypeHandler:
1 | // BaseTypeHandler.java |
然后,父级模板方法调用了 setNonNullParameter 来设置参数,那既然是 UnknownTypeHandler 就需要先判断类型再做事情了。
1 | // UnknownTypeHandler.java |
那寻找到处理器以后,就是 LongTypeHandler 了,继续调用模板方法,这时候就是调用到 LongTypeHandler 的 setNonNullParameter 方法了:
1 | // LongTypeHandler.java |
查询数据
回到我们上面查询数据的方法里面来:
1 |
|
RoutingStatementHandler#query 会路由到 PreparedStatementHandler 里面来,所以现在我们就直接进入 PreparedStatementHandler 看就好了:
1 |
|
处理结果封装
resultSetHandler 是一个 DefaultResultSetHandler:
1 | // DefaultResultSetHandler.java |
OK,那接下来就是怎么封装对象的问题:
1 | // DefaultResultSetHandler.java |
通过属性setter设置结果
1 | // DefaultResultSetHandler.java |
查找属性自动映射器
1 | // DefaultResultSetHandler.java |
设值
metaObject.setValue(mapping.property, value)
1 | // MetaObject.java |
BeanWrapper,一个包装实际对象的封装对象,封装操作这个对象的函数。
1 | // BeanWrapper.java |
好了,所有属性值循环完成,开始出栈,出去到哪里,到 SqlSession 出去。
返回结果对象集
1 |
|