MyBatis源码分析之整体架构认识

时间:2024-03-01 07:00:59

(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨
???????????? 个人博客:小奥的博客
????????????:个人CSDN
⭐️⭐️⭐️:传送门
???? 本人24应届生一枚,技术和水平有限,如果文章中有不正确的内容,欢迎多多指正!
???? 欢迎点赞收藏关注哟! ❤️

文章目录

  • 一、MyBatis整体架构
    • 1.1 项目结构
    • 2 整体架构
      • (1)基础支持层
      • (2)核心处理层
        • ① 配置解析
        • ② SQL解析和scripting模块
        • ③ SQL执行
        • ④ 插件
      • (3)接口层
      • (4)总结

一、MyBatis整体架构

本博文主要是分享自己学习MyBatis源码的一些记录,会参考大量的博文和一些书籍,链接会放在文末。

MyBatis版本:3.5.14

下载源来自Github,fork到自己仓库中,然后clone即可。

1.1 项目结构

如下图,是MyBatis源码的目录结构下的所有包。

在这里插入图片描述

其中,各个包的内容简介如下:

包名称 包内内容简介
annotation 注解目录。包括所有的注解。如@SELECT,@UPDATE
binding Mapper类的实例反射生成工具目录
builder 主要是注解,mapper和SqlSuorce的构造器及转换器
cache Mybatis内部缓存接口。实现了一些特定的缓存策略。FifoCache,LruCache,BlockingCache,LoggingCache
cursor 默认的游标处理类
dataSource 数据源工厂类及实现。实现类包括JndiDataSourceFactoryPooledDataSourceFactoryUnpooledDataSourceFactory。 数据源实现类: UnpooledDataSourcePooledDataSource
exceptions Mybatis自定义的三个异常类。ExceptionFactoryPersistenceExceptionTooManyResultsExceptionIbatisException。都继承自RuntimeException
executor 执行器相关包。包括Key生成器、加载器(包括Cglib、Javassist的代理,结果加载器)、参数处理器接口、结果处理器、结果集(resultSet)处理器、Statement处理器(实现类:BaseStatementHandlerCallableStatementHandlerPreparedStatementHandlerRoutingStatementHandlerSimpleStatementHandler)、执行器(SimpleExecutorReuseExecutorCachingExecutorBatchExecutorBaseExecutor)
io 主要是定义的几个VFS(VFSDefaultVFSClassLoaderWrapper)
jdbc 与Sql相关的操作。如Sql运行器,脚本运行器和Sql封装类等
lang 指定是用java7还是java8的API的注解.UsesJava7UsesJava8
logging 各个类型的日志适配器,都实现了Log接口。StdOutImplSlf4jImplNoLoggingImplLog4j2ImplLog4jImplJdk14LoggingImplBaseJdbcLoggerJakartaCommonsLoggingImpl
mapping 主要是接口参数,sql和返回结果的映射类,主要类包括:MappedStatement,ParameterMap,ParameterMapping,ResultMap,ResultMapping,BoundSql,SqlSource等类
parsing 变量解析.如解析${},#{}
plugin 主要包含插件的定义接口。如Interceptor,Plugin,InterceptorChain
reflection 主要是一些反射操作的工具方法和对象工厂类,以及一些常用的包装类,如BaseWrapper,BeanWrapper,CollectionWrapper,MapWrapper,ObjectWrapper
scripting 执行驱动和动态Sql解析
session 主要是SqlSession和SqlSessionFactory
transaction 主要是mybatis简单封装的jdbc事务操作类
type 各个类型数据的处理器。用于动态的设置参数和转换数据。如IntegerTypeHandler用来处理Integer类型的值的set和get操作。除了八大基本类型。还有常用的集合及Map类型,还增加了各种时间类型的处理器

2 整体架构

MyBatis的整体架构分为三层:基础支持层核心处理层接口层

在这里插入图片描述

(1)基础支持层

基础支持层,包含整个 MyBatis 的基础模块,这些模块为核心处理层的功能提供了良好的支撑

  • 反射模块:对 Java 原生的反射进行良好的封装,进行了一系列的优化,提供更加简洁易用的 API 方便使用。并且对反射操作进行了一系列优化,例如缓存了类的元数据,提高反射操作的性能
  • 类型转换模块:类型转换模块主要提供了两个主要功能,一个是别名机制,MyBatis为了简化配置文件提供了别名机制;另一个功能是实现JDBC类型与Java类型之间的转化,该功能在为SQL语句绑定实参以及映射查询结果集时都会涉及
  • 日志模块:提供日志输出,支持集成第三方日志框架
  • 资源加载模块:主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能
  • 解析器模块:主要提供两个功能,一个是对XPath的封装,为MyBatis初始化时解析mybatis-config.xml配置文件以及映射配置文件提供支持;另一个功能是为处理动态SQL语句中的占位符提供支持
  • 数据源模块:提供相应的 DataSource 数据源实现,支持与第三方数据源的继承
  • 事务模块:对数据库中的事务进行了抽象,提供事务接口的简单实现
  • 缓存模块:提供一级缓存和二级缓存的支持
  • Binding 模块:提供 Mapper 接口与 XML 映射文件进行关联的支持
  • 异常模块:定义 MyBatis 自己的 Exception
  • 注解模块:提供MyBatis相关注解支持

(2)核心处理层

核心处理层实现了MyBatis的核心处理流程,其中包括MyBatis的初始化以及完成一次数据库操作涉及的全部流程。

① 配置解析

在 MyBatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configuration 对象中。之后,利用该 Configuration 对象创建 SqlSessionFactory 对象。待 MyBatis 初始化之后,开发人员可以通过初始化得到 SqlSessionFactory 创建 SqlSession 对象并完成数据库操作。

② SQL解析和scripting模块

MyBatis实现动态SQL功能,提供了多种动态SQL语句对应的节点。如<where><if>等节点,通过这些节点的组合使用,开发人员可以写出几乎满足所有需求的动态SQL语句。

MyBatis 中的 scripting 模块会根据用户传入的实参,解析映射文件中定义的动态 SQL 节点,并形成数据库可执行的 SQL 语句。之后会处理 SQL 语句中的占位符,绑定用户传入的实参。

③ SQL执行

SQL 语句的执行涉及多个组件,其中比较重要的是 ExecutorStatementHandlerParameterHandlerResultSetHandler

Executor 主要负责维护一级缓存和二级缓存,并提供事务管理的相关操作,它会将数据库相关操作委托给StatementHandler 完成。StatementHandler 首先通过 ParameterHandler 完成 SQL 语句的实参绑定;然后通过 java.sql.Statement 对象执行 SQL 语句并得到结果集;最后通过 ResultSetHandler 完成结果集的映射,得到结果对象并返回。

④ 插件

用户可以通过添加自定义插件的方式对 MyBatis 进行扩展。用户自定义插件也可以改变 MyBatis 的默认行为,例如,我们可以拦截 SQL 语句并对其进行重写。由于用户自定义插件会影响 MyBatis 的核心行为,在使用自定义插件之前,开发人员需要了解 MyBatis 内部的原理,这样才能编写出安全、高效的插件。

下图展示了MyBatis执行一条SQL语句的大致过程:

在这里插入图片描述

(3)接口层

接口层相对简单,其核心是SqlSession接口,该接口中定义了MyBatis暴露给应用程序调用的Api,也就是上层应用与MyBatis交互的桥梁。接口层在收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。

(4)总结

MyBatis的代码并不是很多,相对于源码阅读入门的同学来说还是比较简单的,我会按照以上三个模块(基础支持层 ==> 核心处理层 ==> 接口层)进行逐步分析。