剑指源码-Mybatis-(二)-主流程分析与核心组件关系
本文最后更新于:2024年4月22日 下午
demo整体流程概述,分析核心组件的作用以及关系
demo地址:https://github.com/hyq965672903/sourcecode-learn-mybatis.git
整体流程分析
通过 SqlSession.getMapper(XXXMapper.class) 接口方式为例,流程分析
创建SqlSessionFactory的过程
首先根据mybatis-config.xml创建一个
inputStream
然后new一个SqlSessionFactoryBuilder对象,使用inputStream调用build方法得到
SqlSessionFactory
对象XMLConfigBuilder
创建的parser解析器对象,会去解析每一个xml节点信息,对应的相关配置信息保存在一个Configuration
对象中同时这个时候会解析到mapper信息,
XMLConfigBuilder
内部构建了一个XMLMapperBuilder
,XMLMapperBuilder
对象会将mappper信息解析到Configuration
的mappedStatements
这个Map对象中。而这个mappedStatements
包含多个MappedStatement
,MappedStatement
中包含了mapper中每一个标签信息解析完mapper之后,将mapper的信息放入
Configuration
对象中,返回Configuration
对象build中传入的Configuration对象被用来创建了一个
DefaultSqlSessionFactory
对象。创建sqlSessionFactory所做的工作就是,将所有配置文件的信息解析并且保存在Configuration对象中,返回包含了Configuration对象的DefaultSqlSessionFactory对象。
获取sqlSession对象的过程
- 首先调用
DefaultSqlSessionFactory
的openSession
()方法 - openSession里面调用
openSessionFromDataSource
(configuration.getDefaultExecutorType(), null, false)方法 openSessionFromDataSource
里面会创建Transaction一个事务,同时会创建一个Executor对象- 根据
Executor
在全局配置中的类型(目前类型有3种,simple,batch,reuse),创建出SimpleExecutor、ReuseExecutor
或者BatchExecutor
。Executor是一个接口,里面规定了一些增删改查的接口方法。默认就是simple类型 - 如果开启了二级缓存,会通过CacheExecutor对Executor进行包装,CacheExecutor本质就是装饰者模式
- executor = (Executor) interceptorChain.pluginAll(executor),pluginAll方法会拿到每一个拦截器的plugin方法包装一下executor,开发插件就是这里织入
- 最后创建DefaultSqlSession并返回
创建Executor代码逻辑
获取Mapper的代理对象(MapperProxy)的过程
- 调用
DefaultSqlSession
对象的getMapper(type)方法。(type是Mapper接口的class,例如XXXMapper.class) - 进一步里面会调用
configuration
.getMapper(type,sqlSession),调用configuration
对象中mapperRegistry
的getMapper - 然后根据class类型获取
MapperProxyFactory
,调用其newInstance
,进而使用MapperProxy
动态代理创建代理对象,并返回
执行增删改查方法的过程
Mapper
都是接口,所以最终执行都会执行到MapperProxy
的invoke
方法MapperProxy
的invoke会执行MapperMethod
的execute,execute方法会判断当前要执行的sql语句的类型当前是selectAll,于是执行到
executeForMany
方法,进而sqlSession
执行到selectList方法selectList方法中获取
MappedStatement
对象,调用executor
(CachingExecutor)执行query获取BoundSql对象,里面包含sql语句的详细信息。sql语句是什么、sql语句的参数是什么等详细信息
调用真正的
simpleExecutor
的query方法进行查询,query是BaseExecutor
中的,真正执行到doQuery方法doQuery里面会创建
StatementHandler
,默认就是PreparedStatementHandler
。StatementHandler
被用于创建Statement对象。同时这里StatementHandler
会执行interceptorChain的pluginAll进行插件加载在
StatementHandler
会调用父类BaseStatementHandler
的构造方法进一步创建ParameterHandler
和ResultSetHandler
ParameterHandler
用于处理参数设置的 ,设置sql语句的预编译参数ResultSetHandler
用于处理结果返回封装的
ParameterHandler
和ResultsetHandler
都会借助TypeHandler
来进行数据库类型和Java Bean类型的转换ParameterHandler
设置参数的时候是调用的TypeHandler
给sql预编译设置参数查出数据之后,使用
ResultHandler
处理结果,里面也是使用TypeHandler
包装value值后续操作完成数据库连接相关
流程结束
Executor、ParameterHandler、ResultsetHandler、TypeHandler四大对象之间的关系
Executor用于执行增删改查操作;StatementHandler用ParameterHandler设置参数;使用ResultsetHandler处理结果;过程中又采用TypeHandler来实现数据库类型和JavaBean类型之间的转换