2020-08-26 myBatis执行流程全解析

概要:

[if !supportLists]1. [endif]执行流程解析

[if !supportLists]2. [endif]myBatis插件开发


一、执行流程解析

配置文件解析configuration:

讲解解析流程之前先回顾一下myBatis 中配置文件的结构:

mybatis-config.xml

<configuration>

  <properties/>

  <settting/>

  <typeHandlers/>

  <..../>

  <mappers/>

</configuration>

mybatis-mapper.xml

<mapper >

  <cache/>

  <resultMap/>

  <select/>  

  <update/> 

  <delete/> 

  <insert/> 

</mapper>


配置文件的解析流程即是将上述XML描述元素转换成对应的JAVA对像过程,其最终转换对像及其关系如下图:



配置元素解析构建器

>org.apache.ibatis.builder.xml.XMLConfigBuilder

 >org.apache.ibatis.builder.xml.XMLMapperBuilder

  >org.apache.ibatis.builder.xml.XMLStatementBuilder

   >org.apache.ibatis.builder.SqlSourceBuilder

    >org.apache.ibatis.scripting.xmltags.XMLScriptBuilder

 >org.apache.ibatis.builder.annotation.MapperAnnotationBuilder


sql statement 构建流程源码:

>org.apache.ibatis.session.SqlSessionFactoryBuilder#build()

//1.Config.xml 文件解析

 >org.apache.ibatis.builder.xml.XMLConfigBuilder#parse()

  >org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration()

   >org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement()

// 2.Mapper.xml 文件解析

    >org.apache.ibatis.builder.xml.XMLMapperBuilder#parse()

     >org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement()

      >org.apache.ibatis.builder.xml.XMLMapperBuilder#buildStatementFromContext()

//3.Statemen sql块解析

       >org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode

        >org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement()

// 4.动态SQL脚本解析

>org.apache.ibatis.scripting.xmltags.XMLLanguageDriver#createSqlSource()

>org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseScriptNode()

>org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseDynamicTags()

会话创建SqlSession

首先我们还是先来了解一下会话对像的组成结构如下图:




会话构建源码解析:

>org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession(boolean)

 >org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource

 >org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory#newTransaction()

 >org.apache.ibatis.session.Configuration#newExecutor()

 >org.apache.ibatis.executor.SimpleExecutor#SimpleExecutor

 >org.apache.ibatis.executor.CachingExecutor#CachingExecutor

  //执行器插件包装

 >org.apache.ibatis.plugin.InterceptorChain#pluginAll(executor)

 >org.apache.ibatis.session.defaults.DefaultSqlSession#DefaultSqlSession()

方法执行StatementHandler



StatementHandler 源码解析

>org.apache.ibatis.session.defaults.DefaultSqlSession#selectList()

 >org.apache.ibatis.executor.CachingExecutor#query()

  >org.apache.ibatis.executor.BaseExecutor#query()

   >org.apache.ibatis.executor.BaseExecutor#queryFromDatabase

>org.apache.ibatis.session.Configuration#newStatementHandler

org.apache.ibatis.executor.statement.BaseStatementHandler#BaseStatementHandler

org.apache.ibatis.session.Configuration#newParameterHandler

org.apache.ibatis.plugin.InterceptorChain#pluginAll(parameterHandler)

org.apache.ibatis.session.Configuration#newResultSetHandler

org.apache.ibatis.plugin.InterceptorChain#pluginAll(resultSetHandler)

>org.apache.ibatis.plugin.InterceptorChain#pluginAll(statementHandler)

>org.apache.ibatis.executor.BaseExecutor#getConnection

>org.apache.ibatis.executor.statement.PreparedStatementHandler#instantiateStatement

>org.apache.ibatis.executor.statement.PreparedStatementHandler#parameterize

>org.apache.ibatis.scripting.defaults.DefaultParameterHandler#setParameters

org.apache.ibatis.type.BaseTypeHandler#setParameter

org.apache.ibatis.type.UnknownTypeHandler#setNonNullParameter

org.apache.ibatis.type.IntegerTypeHandler#setNonNullParameter

Mapper接口实例构建



二、myBatis插件开发

插件的四大扩展点

[if !supportLists]1. [endif]Executor

[if !supportLists]2. [endif]StatementHandler

[if !supportLists]3. [endif]ParameterHandler

[if !supportLists]4. [endif]ResultSetHandler


分页插件实现:

用户在接口中声明Page  对像实现后,由插件实现自动分页。使用示例如下:


public class Page implements java.io.Serializable {

    private int szie; // 每页大

    private int number; // 当前页码

}


page参数声明

@Select("select * from user")

List<User> selectByPage(String name, Page page);


客户端调用

mapper.selectByPage("小明", new Page(3, 2))


select * from user  limit 10,20

实现目标分解:

[if !supportLists]1. [endif]修改修改SQL 并添加 limit 语句

[if !supportLists]2. [endif]判断方法参数中是否有Page对象

[if !supportLists]3. [endif]取出Page对象 生成limit 语句

[if !supportLists]4. [endif]上述操作必须在PreparedStatement 对像生成前完成

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。