1. 配置文件初始化
1.1 加载配置文件,并将配置文件加载到内存中
1.2 解析配置文件
1.2.1 进入到SqlSessionFactoryBuilder中的build方法,看到如下内容
1.2.2 进入重载方法中
Configuration对象的结构和xml配置文件的对象几乎相同。
回顾一下xml中的配置标签有哪些:
properties (属性),
settings (设置),
typeAliases (类型别名),
typeHandlers (类型处理器),
objectFactory (对象工厂),
mappers (映射器) 等 Configuration也有对应的对象属性来封装它们,也就是说,初始化配置文件信息的本质就是创建Configuration对象,将解析的xml数据封装到Configuration内部属性中。
1.2.3 解析 XML 成 Configuration 对象
进入parseConfiguration方法可以看到如下内容:
从上图中可以看到就是针对于mybatis-config.xml文件的内容解析,而且是按照全量去解析的,也就是说在这一步解析过程总会将数据库的配置信息、缓存等配置信息加载到Configuration对象中去。
1.3 MappedStatement
作用: MappedStatement与Mapper配置文件中的一个select/update/insert/delete节点相对应。也就是说每一段要执行的SQL在配置信息中都维护了MappedStatement对象。
1.3.1 加载Mapper文件
1.3.2 解析Mapper文件
进入到mapperParser.parse()方法中,解析Mapper节点
解析Mapper中使用select/update/insert/delete的代码块,并将其封装成一个MappedStatement对象:
1.4 调用重载方法,加载Configuration对象
到此也就完成了xml文件的解析,解析大概可以分为两个步骤:
- 解析mybatis-config.xml文件,加载相关配置信息到Configuration对象中,并且按照Mapper标签加载对应的Mapper.xml文件
- 解析Mapper.xml 文件,将Mapper.xml文件中的每个SQL相关的操作(select/update/insert/delete的代码块)封装成一个MappedStatement对象,并且调用Configuration对象的addMappedStatement方法存放到Configuration对象中
2. SQL执行流程
2.1 SqlSession对象介绍
SqlSession是一个接口,它有两个实现类:DefaultSqlSession (默认)和SqlSessionManager (弃用,不做介绍)。
SqlSession是MyBatis中用于和数据库交互的顶层类,通常将它与ThreadLocal绑定,一个会话使用一 个SqlSession,并且在使用完毕后需要close。
可以看到DefaultSqlSession有两个重要的参数:
Configuration: 在初始化过程中已加载
Executor: 这个在后面再介绍
下面我们开始执行SQL
2.2 build.openSession()方法解析
2.3 执行selectList()方法
从上面可以看到,执行一个selectList方法就是获取一个MappedStatement对象,然后再由Executor执行器去执行查询的方法。
3. Executor
3.1 query方法执行
重载进入query方法
从数据库中查询,执行queryFromDatabase方法
执行查询操作doQuery
由StatementHandler执行查询操作,那么需要先初始化一个:
上述的Executor.query()方法几经转折,最后会创建一个StatementHandler对象,然后将必要的参数传递给StatementHandler,使用StatementHandler来完成对数据库的查询,最终返回List结果集。
从上面的代码中我们可以看出,Executor的功能和作用是:
(1、根据传递的参数,完成SQL语句的动态解析,生成BoundSql对象,供StatementHandler使用;
(2、为查询创建缓存,以提高性能
(3、创建JDBC的Statement连接对象,传递给StatementHandler对象,返回List查询结果。
4. StatementHandle
StatementHandler对象主要完成两个工作:
(1) 对于JDBC的PreparedStatement类型的对象,创建的过程中,我们使用的是SQL语句字符串会包含若干个?占位符,我们其后再对占位符进行设值。StatementHandler通过parameterize(statement)方法对 Statement 进行设值;
(2) StatementHandler 通过 List query(Statement statement, ResultHandler resultHandler)方法来完成执行Statement,和将Statement对象返回的resultSet封装成List;
进入到 StatementHandler 的 parameterize(statement)方法的实现:
从上述的代码可以看到,StatementHandler的parameterize(Statement)方法调用了
ParameterHandler的setParameters(statement)方法,
ParameterHandler的setParameters(Statement )方法负责根据我们输入的参数,对statement对象的"?"占位符处进行赋值。
进入到StatementHandler 的 List query(Statement statement, ResultHandler resultHandler)方法的实现:
从上述代码我们可以看出,StatementHandler 的List query(Statement statement, ResultHandler resultHandler)方法的实现,是调用了 ResultSetHandler 的 handleResultSets(Statement)方法。