MyBatis源码的学习(23)---阶段性总结

按功能模块分:

  1. sql解析阶段
  2. sql执行阶段
    先看解析阶段
@BeforeAll
static void initDatabase() throws Exception {
  try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml")) {
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
  }
}

方法的调用链:

【SqlSessionFactoryBuilder】#bulid
         |--【XMLConfigBuilder】#new
         |--【XMLConfigBuilder】#parse
           |--parseConfiguration (注释 同一个类中的方法调用,省去前面的类名部分)
               |---xxxxxx
               |---environmentsElement
                   |---mapperElement
                       |--【XMLMapperBuilder】#new
                       |--【XMLMapperBuilder】#parse
                             |--configurationElement
                                  |--xxxxxx
                                  |--buildStatementFromContext
                                        |--【XMLStatementBuilder】#new
                                        |--【XMLStatementBuilder】#parseStatementNode
                                             |--【XMLLanguageDriver】#createSqlSource
                                                   |--【XMLScriptBuilder】#new
                                                   |--【XMLScriptBuilder】#parseScriptNode
                                                         |---parseDynamicTags
                                                         |---DynamicSqlSource#new
                                                         |---RawSqlSource#new
                                             |--【MapperBuilderAssistant】#addMappedStatement
            

上面只是冰山一角,只列出了解析Mapper的Resource这种方式的。一共四种解析Mapper的方式。
然后看sql的执行阶段:

//3、获取mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4、执行数据库操作,并处理结果集
return userMapper.selectOne("10");

方法的调用链:

【DefaultSqlSession】#getMapper
   |--【Configuration】#getMapper
      |--【MapperRegistry】#getMapper
         |--knownMappers.get(type)  -->MapperProxyFactory(代表返回值类型)
         |--【MapperProxyFactory】#newInstance
           |--【MapperProxy】#new
           |--newInstance
              |--【Proxy】#newProxyInstance

上面是getMapper的调用链,由此看出走的jdk的动态代理
下面看selectOne这个方法的调用链,jdk动态代理,直接看我们MapperProxy(实现了InvocationHandler接口)的invoke方法。

【MapperProxy】#invoke
   |--cachedInvoker-->MapperMethodInvoker(PlainMethodInvoker是实现类)(代表返回类型)
   |--【PlainMethodInvoker】#invoke
      |--【MapperMethod】#execute
          |--【MethodSignature】#convertArgsToSqlCommandParam
          |--【DefaultSqlSession】#selectOne
             |--selectList
               |--【Configuration】#getMappedStatement
               |--【CachingExecutor】#query(这儿根据配置,这是开启二级缓存时)
                 |--【MappedStatement】#getBoundSql
                 |--createCacheKey
                 |--query
                   |--tcm.getObject (查二级缓存,不存在则走下面方法)
                   |--【BaseExecutor】#query
                       |--localCache.getObject  (从一级缓存查,没有则走下面方法)
                       |--queryFromDatabase
                         |--【SimpleExecutor】doQuery
                            |--【MappedStatement】#getConfiguration
                            |--【Configuration】newStatementHandler
                            |--prepareStatement (建立连接,statement对象创建,参数赋值)
                              |--getConnection 
                              |--【RoutingStatementHandler】#prepare
                                 |--【PreparedStatementHandler】prepare
                              |--【RoutingStatementHandler】#parameterize
                                 |--【PreparedStatementHandler】#parameterize                                               
                            |--【RoutingStatementHandler】#query
                              |--【PreparedStatementHandler】#query
                                 |--【PreparedStatement】#execute
                                 |--【DefaultResultSetHandler】#handleResultSets (进行jdbc结果集转java类型结果集操作)

上面的总结相当于建立了一个目录,在这个目录下,如果想要看具体的细节,可以看之前的文章。
比如:
MyBatis源码的学习(5)—设计模式的使用
MyBatis源码的学习(10)—高版本的Mapper.XML中为何不能使用#{0},#{1}操作?
MyBatis源码的学习(11)—Mybatis二级缓存默认LRU算法的分析
MyBatis源码的学习(16)—拦截器为何不能拦截Executor中6个参数的query方法
MyBatis源码的学习(18)—如何对statement对象进行参数赋值操作的?
MyBatis源码的学习(19)—如何将jdbc的返回结果resultSet处理为我们想要的java类型
MyBatis源码的学习(22)—关于#和 的 区 别 , 简 单 类 型 的区别,简单类型 中只能用value吗??

你可能感兴趣的:(Mybatis源码学习)