MyBatis设计架构
MyBatis 的整体架构分为三层, 分别是基础支持层、核心处理层和接口层,如下图所示:
源码解析
我们在使用mybatis的时候核心是 SqlSession 接口,该接口中定义了 MyBatis 暴露给应用程序调用的 API,也就是上层应用与 MyBatis 交互的桥梁。接口层在接收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。
构建Configuration类
这里就是读取mybatis-config.xml配置进行解析.
整个mybatis-config.xml配置包含如下节点的解析
org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
创建SqlSession对象
这里包含了开启事务,自动提交为false.
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
综述上边获取session的流程如下所示:
创建MapperProxy对象
由于mybatis的dao层使用的是接口形式.通过接口是无法调用对应的方法,所以mybatis通过创建MapperProxy代理类来调用对应的接口.
org.apache.ibatis.session.Configuration#getMapper
org.apache.ibatis.binding.MapperRegistry#getMapper
org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession)
创建MapperProxy流程如下
执行mapper方法
当调用mapper方法时,会走到代理类的invoke方法
下面方法org.apache.ibatis.binding.MapperProxy#invoke
org.apache.ibatis.binding.MapperProxy.PlainMethodInvoker#invoke
接着执行 MapperMethod.execute(sqlSession, args) 方法。
进入org.apache.ibatis.binding.MapperMethod#execute()方法后,我们关注查询接口如下:
org.apache.ibatis.session.defaults.DefaultSqlSession#selectList()
org.apache.ibatis.executor.statement.PreparedStatementHandler#instantiateStatement
通过上面的分析,简单总结一下,我们可以抽象出 MyBatis 在执行一条 SQL 查询的过程中涉及到的主要类:Configuration、SqlSession、MapperProxy、Exector,根据这些类画出如下 MyBatis 执行 SQL 的时序图:
调用Exector实现类实现查询与返回
SqlSession 中的 JDBC 操作部分最终都会委派给 Exector 实现,接着上面的断点往下执行,进入 Exector 的 query 方法。
下面通过时序图描述 Exector 的执行流程,真实的调用链路类比较多,这里简化了调用链路,省略了一些装饰类、代理类,便于理解:
根据 Exector 执行的时序图,可以抽象出的主要类是:
- SqlSession
- Exector
- StatementHandler
- ParameterHandler
- ResultSetHandler
StatementHandler 接口是 MyBatis 的核心接口之一,它是 Exector 接口实现的基础。StatementHandler 的主要功能很多,例如创建 Statement 对象,为 SQL 语句绑定实参,执行 SQL 语句,将结果集映射成结果对象。
StatementHandler 类中包含了 ParameterHandler 和 ResultSetHandler 的属性。ParameterHandler 的主要功能是为 SQL 语句绑定实参,也就是使用传入的参数替换 SQL 语句中的“?”占位符。ResultSetHandler 的主要功能是将结果集映射成结果对象。
总体流程可以分如下两张图
总结
总结一下mybatis的原理,简单分如下几步
- 读取配置构建Configuration.
- 通过配置创建DefaultSqlSessionFactory工厂类
- 通过DefaultSqlSessionFactory创建SqlSession
- 创建事务工厂
- 创建事务管理器
- 创建执行器
- 通过SqlSession去获取MapperProxy代理类
- SqlSession.getMapper()调用configuration.getMapper()调用mapperRegistry.getMapper最后获取MapperProxyFactory
- 通过MapperProxyFactory 生成MapperProxy
- 通过SqlSession调用Exector创建StatementHandler
- 通过StatementHandler调用ParameterHandler 处理参数
- 通过prepareStatement执行sql
- 通过StatementHandler调用ResultSetHandler 处理返回结果
[参考]:mybatis源码编译
mybatis-3-mybatis-3.5.7.zip
parent-mybatis-parent-32.zip
mck-mybatis-3-mybatis-3.5.7.zip
里面图片有些来自网上copy。