MyBatis 源码分析-项目总览

1.概述

本文主要大致介绍一下MyBatis的项目结构。引用参考资料《MyBatis技术内幕》

此外,https://mybatis.org/mybatis-3/zh/index.html MyBatis官方也提供了很不错的中文文档。对于使用中有碰到一些问题,可以参考一下。

2.模块划分

MyBatis在项目模块划分还是很清晰的。各个模块层次以及具体作用,如下:

模块 层次 定义
session 接口层 提供给外部使用的接口API
scripting 核心处理层 解析映射文件中的动态SQL节点。并形成数据库可执行的SQL语句。
mapping 核心处理层 映射
builder 核心处理层 配置解析
executor 核心处理层 执行器模块,串联整个执行流程。
plugin 核心处理层 插件模块:提供插件接口,通过自定义插件方式对MyBatis进行拓展
cursor 核心处理层 游标模块
reflection 基础支持层 反射模块:mybatis专门对反射模块进行封装。提供更加简单易用的API
type 基础支持层 类型转换模块:Mybatis为简化配置提供了别名机制。提供java类型与JDBC类型转换
logging 基础支持层 日志模块:主要是集成第三方日志
io 基础支持层 资源加载模块:对类加载器进行了封装。确定类加载器顺序,并提供加载文件,以及其他资源的功能
datasource 基础支持层 数据源模块:mybatis自身提供响应的数据源实现,也提供与第三方数据集成的接口。
transaction 基础支持层 事务管理模块:Mybatis 对数据库的事务进行了抽象
parsing 基础支持层 解析器模块:提供两个功能:1. 对XPath进行封装 2为处理动态sql语句中的占位符提供支持
cache 基础支持层 缓存模块:提供一级缓存、二级缓存。优化查询
binding 基础支持层 Binding模块:将自定义的接口与映射配置文件关联起来。通过调用mapper接口完成数据库执行。
exceptions 基础支持层 异常处理
annotations 基础支持层 注解模块
jdbc 其他 JDBC模块
lang 其他 Lang模块

整体结构

整体分为三层:

  • 接口层:定义了MyBatis暴露给应用程序调用的API。
  • 核心处理层:实现了MyBatis的核心处理流程,包括MyBatis初始化以及完成一次数据库操作的涉及的全部流程。
  • 基础支持层:为核心处理层提供了良好的基础支撑。例如:反射、类型转换、日志、缓存、事务等模块。

3.1 基础支持层

3.1.1 反射模块

对应reflection

Java中的反射虽然功能强大,但对大多数开发人员来说,写出高质量的反射代码还是有一定难度的。MyBatis 中专门提供了
反射模块,该模块对Java原生的反射进行了良好的封装,提供了更加简洁易用的API, 方便上层使调用,并且对反射操作进行
了一系列优化,例如缓存了类的元数据,提高了反射操作的性能。

3.1.2 类型转换模块

对应type

正如前面示例所示,MyBatis 为简化配置文件提供了别名机制,该机制是类型转换模块的主要功能之一。 类型转换模块的
另-一个功能是实现JDBC类型与Java类型之间的转换,该功能在为SQL语句绑定实参以及映射查询结果集时都会涉及。在为
SQL语句绑定实参时,会将数据由Java类型转换成JDBC类型;而在映射结果集时,会将数据由JDBC类型转换成Java类型。类
型转换模块的具体原理在第2章详述。

3.1.3 日志模块

对应logging

无论在开发测试环境中,还是在线上生产环境中,日志在整个系统中的地位都是非常重要的。良好的日志功能可以帮助开发人
员和测试人员快速定位Bug代码,也可以帮助运维人员快速定位性能瓶颈等问题。目前的Java世界中存在很多优秀的日志框
架,例如Log4j、Log4j2、 slf4j 等。MyBatis 作为-一个设计优良的框架,除了提供详细的日志输出信息,还要能够集
成多种日志框架,其日志模块的一个主要功能就是集成第三方日志框架。

3.1.4 资源加载模块

对应io

资源加载模块主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能。

3.1.5 解析器模块

对应parsing

解析器模块的主要提供了两个功能:一个功能是对XPath进行封装,为MyBatis初始化时解析mybatis- config.xml配置文
件以及映射配置文件提供支持;另一个功能是为处理动态SQL语句中的占位符提供支持。

3.1.6 数据源模块

对应datasource

数据源是实际开发中常用的组件之一。 现在开源的数据源都提供了比较丰富的功能,例如,连接池功能、检测连接状态等,
选择性能优秀的数据源组件对于提升ORM框架乃至整个应用的性能都是非常重要的。MyBatis 自身提供了相应的数据源实
现,当然MyBatis也提供了与第三方数据源集成的接口,这些功能都位于数据源模块之中。

3.1.7 事务管理

对应transaction

MyBatis对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。在很多场景中,MyBatis 会与Spring
框架集成,并由Spring框架管理事务

3.1.8 缓存模块

对应cache

在优化系统性能时,优化数据库性能是非常重要的一个环节,而添加缓存则是优化数据库时最有效的手段之一。正确、合理地
使用缓存可以将一部分数据库请求拦截在缓存这一层。MyBatis 中提供了一 级缓存和二级缓存,而这两级缓存都是依赖于基
础支持层中的缓存模块实现的。这里需要读者注意的是,MyBatis中自带的这两级缓存与MyBatis 以及整个应用是运行在同
一个JVM中的,共享同一块堆内存。如果这两级缓存中的数据量较大,则可能影响系统中其他功能的运行,所以当需要缓存大
量数据时,优先考虑使用Redis、Memcache 等缓存产品。

3.1.9 Binding模块

对应binding

通过前面的示例我们知道,在调用SqlSession相应方法执行数据库操作时,需要指定映射文件中定义的SQL节点,如果出现
拼写错误,我们只能在运行时才能发现相应的异常。为了尽早发现这种错误,MyBatis 通过Binding模块将用户自定义的
Mapper接口与映射配置文件关联起来,系统可以通过调用自定义Mapper接口中的方法执行相应的SQL语句完成数据库操作,
从而避免上述问题。值得读者注意的是,开发人员无须编写自定义Mapper接口的实现,MyBatis 会自动为其创建动态代理对
象。在有些场景中,自定义Mapper接口可以完全代替映射配置文件,但有的映射规则和SQL语句的定义还是写在映射配置文件
中比较方便,例如动态SQL语句的定义。

3.1.10 注解模块

对应annotation

随着 Java 注解的慢慢流行,MyBatis 提供了注解的方式,使得我们方便的在 Mapper 接口上编写简单的数据库 SQL 操作代码,而无需像之前一样,必须编写 SQL 在 XML 格式的 Mapper 文件中。虽然说,实际场景下,大家还是喜欢在 XML 格式的 Mapper 文件中编写响应的 SQL 操作。

3.1.11 异常模块

对应 exceptions

定义了 MyBatis 专有的 PersistenceException 和 TooManyResultsException 异常,此外还包ExceptionFactory异常工厂。

3.2 核心处理层

3.2.1 配置解析

对应executor

在MyBatis初始化过程中,会加载mybatis config.xml配置文件、映射配置文件以及Mapper接口中的注解信息,解析后
的配置信息会形成相应的对象并保存到Configuration对象中。例如,示例中定义的<resultMap>节点(即ResultSet的映
射规则)会被解析成ResultMap对象;示例中定义的<result>节点(即属性映射)会被解析成ResultMapping对象。之后,利
用该Configuration对象创建SqlSessionFactory对象。待MyBatis 初始化之后,开发人员可以通过初始化得到
SqlSessionFactory 创建SqlSession对象并完成数据库操作。

3.2.2 SQL解析与Scripting模块

对应executor scripting

拼凑SQL语句是一件烦琐且易出错的过程,为了将开发人员从这项枯燥无趣的工作中解脱出来,MyBatis实现动态SQL语句的
功能,提供了多种动态SQL语句对应的节点,例如,<where>节点、 <if>节点、 <foreach> 节点等。通过这些节点的组合
使用,开发人员可以写出几乎满足所有需求的动态SQL语句。MyBatis中的scripting模块会根据用户传入的实参,解析映射
文件中定义的动态SQL节点,并形成数据库可执行的SQL语句。之后会处理SQL语句中的占位符,绑定用户传入的实参。

3.2.3 SQL执行

对应executor

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

3.2.4 插件

对应plugin

Mybatis 自身的功能虽然强大,但是并不能完美切合所有的应用场景,因此MyBatis提供了插件接口,我们可以通过添加用
户自定义插件的方式对MyBatis进行扩展。用户自定义插件也可以改变Mybatis的默认行为,例如,我们可以拦截SQL语句并
对其进行重写。由于用户自定义插件会影响MyBatis的核心行为,在使用自定义插件之前,开发人员需要了解MyBatis内部的
原理,这样才能编写出安全、高效的插件。

3.3 接口层

对应session

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

3.4 其他层

3.4.1 JDBC模块

对应 jdbc

JDBC单元测试支持类。【只能说是个测试挂件,白送都不要的那种,随便看看得了 】

3.4.2 Lang模块

里面只包含两个注解【从调用上好像没有任何类用到这个。不知道干啥用的!!原谅我的无知。】

3.5 小结

整体来说,MyBatis的代码结构还是比较简单易懂的。并且分包也比较清晰,见名知意。下面就是MyBatis的整体架构图

MyBatis 源码分析-项目总览的更多相关文章

  1. mybatis源码分析(一)

    mybatis源码分析(sqlSessionFactory生成过程) 1. mybatis框架在现在各个IT公司的使用不用多说,这几天看了mybatis的一些源码,赶紧做个笔记. 2. 看源码从一个d ...

  2. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  3. MyBatis 源码分析系列文章导读

    1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...

  4. MyBatis 源码分析

    MyBatis 运行过程 传统的 JDBC 编程查询数据库的代码和过程总结. 加载驱动. 创建连接,Connection 对象. 根据 Connection 创建 Statement 或者 Prepa ...

  5. (一) Mybatis源码分析-解析器模块

    Mybatis源码分析-解析器模块 原创-转载请说明出处 1. 解析器模块的作用 对XPath进行封装,为mybatis-config.xml配置文件以及映射文件提供支持 为处理动态 SQL 语句中的 ...

  6. 精尽 MyBatis 源码分析 - 整体架构

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  7. 精尽MyBatis源码分析 - MyBatis-Spring 源码分析

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  8. 精尽MyBatis源码分析 - Spring-Boot-Starter 源码分析

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  9. MyBatis源码分析-MyBatis初始化流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

随机推荐

  1. mysql 多字段更新

    更新一个字段当好写 ; Query OK, rows affected (17.36 sec) Rows matched: Changed: Warnings: 问题是想更新多个字段sql serve ...

  2. Python使用pycharm导入pymysql(MySQL)或pymssql(SQLServer)

    file->setting->project->project interperter,双击右侧出现的pip,弹出安装包,搜索pymysql->选择第一个->Instal ...

  3. [LC] 442. Find All Duplicates in an Array

    Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others ...

  4. try中定义的变量在finally中找不到

    凡是代码块中的变量,作用域都只在代码块中 https://blog.csdn.net/qq_20936333/article/details/81062966 问题: 解决:

  5. Linux下Centos 7如何关闭防火墙?

    Linux下的防火墙有两种:Iptables和Firewall(概念以及区别大家可以自行搜索).为什么要关闭防火墙呢?主要是我们都过Linux搭建服务器的时候其他机器访问会被墙掉,例如:Tomcat, ...

  6. idea 集成svn

    1.下载svn客户端 官网下载地址:https://tortoisesvn.net/downloads.html 2. 安装svn客户端 在安装svn客户端的时候一定要勾选,否则在idea上集成svn ...

  7. (七)spring+druid多数据源配置

    druid多数据源配置 一.druid简介 Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser. ...

  8. 微软Project Oxford帮助开发人员创建更智能的应用

    Oxford帮助开发人员创建更智能的应用" title="微软Project Oxford帮助开发人员创建更智能的应用"> 假设你是一名对关于健身的应用充满奇思妙想 ...

  9. TICA 2019 自动的自动化测试——智能化一站式的API测试服务

    阿里QA导读:新奥集团中台的陈磊为我们打开了AI测试驱动的视野,同时也深入浅出地介绍了如何打造智能化API测试框架.通过陈磊老师的分享,我们看到了AI-DT的无限可能性.以后,AI能不能代替大部分手动 ...

  10. CentOS使用epel安装不同版本php-fpm

    针对CentOS使用epel安装 yum -y install epel-release安装好后可以通过如下命令查看yum info epel-releaseyum repolist查看php版本ph ...