MyBatis源码分析之整体架构认识
作者:mmseoamin日期:2024-04-01

(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨

👀👀👀 个人博客:小奥的博客

👍👍👍:个人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源码的目录结构下的所有包。

          MyBatis源码分析之整体架构认识,在这里插入图片描述,第1张

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

          包名称包内内容简介
          annotation注解目录。包括所有的注解。如@SELECT,@UPDATE等
          bindingMapper类的实例反射生成工具目录
          builder主要是注解,mapper和SqlSuorce的构造器及转换器
          cacheMybatis内部缓存接口。实现了一些特定的缓存策略。FifoCache,LruCache,BlockingCache,LoggingCache等
          cursor默认的游标处理类
          dataSource数据源工厂类及实现。实现类包括JndiDataSourceFactory、PooledDataSourceFactory、UnpooledDataSourceFactory。 数据源实现类: UnpooledDataSource、PooledDataSource
          exceptionsMybatis自定义的三个异常类。ExceptionFactory、PersistenceException、TooManyResultsException、IbatisException。都继承自RuntimeException
          executor执行器相关包。包括Key生成器、加载器(包括Cglib、Javassist的代理,结果加载器)、参数处理器接口、结果处理器、结果集(resultSet)处理器、Statement处理器(实现类:BaseStatementHandler、CallableStatementHandler、PreparedStatementHandler、RoutingStatementHandler、SimpleStatementHandler)、执行器(SimpleExecutor、ReuseExecutor、CachingExecutor、BatchExecutor、BaseExecutor)
          io主要是定义的几个VFS(VFS、DefaultVFS、ClassLoaderWrapper)
          jdbc与Sql相关的操作。如Sql运行器,脚本运行器和Sql封装类等
          lang指定是用java7还是java8的API的注解.UsesJava7、UsesJava8
          logging各个类型的日志适配器,都实现了Log接口。StdOutImpl、Slf4jImpl、NoLoggingImpl、Log4j2Impl、Log4jImpl、Jdk14LoggingImpl、BaseJdbcLogger、JakartaCommonsLoggingImpl
          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的整体架构分为三层:基础支持层、核心处理层和接口层。

          MyBatis源码分析之整体架构认识,在这里插入图片描述,第2张

          (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语句对应的节点。如等节点,通过这些节点的组合使用,开发人员可以写出几乎满足所有需求的动态SQL语句。

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

            ③ SQL执行

            SQL 语句的执行涉及多个组件,其中比较重要的是 Executor 、StatementHandler 、ParameterHandler 和 ResultSetHandler。

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

            ④ 插件

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

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

            MyBatis源码分析之整体架构认识,在这里插入图片描述,第3张

            (3)接口层

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

            (4)总结

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