作为正式内容的第一篇,本次不会介绍具体的技术,而是先从全局视角上对 MyBatis 做一个俯瞰,了解 MyBatis 项目工程的组织结构,以及内部的核心功能模块。
工程结构
打开 MyBatis 的 Github 地址,就可以看到其代码工程结构。MyBatis 的分包方式简洁清晰、见名知义,可以清晰地看出内部的功能模块。下面我对其中较为核心的模块进行下简单介绍:
- annotatios:注解开发模块,定义了所有 Mapper 接口中用到的注解,常用的如 @Param,@Update、@Select、@Delete 等。
- binding:数据绑定模块,通过动态代理方式生成 Mapper 接口的实现类,并对其生命周期进行管理。
- builder:构建器模块,基于构建者模式(Builder Pattern),定义了 MyBatis 内部所有的构建器。MyBatis 的核心组件大部分都是通过 Builder 来构造的。
- cache:缓存模块,内置了各种缓存装饰器(Decorator),MyBatis 中耳熟能详的一级缓存、二级缓存就是基于该模块来实现的。
- cursor:支持游标的方式的数据查询,比较适合处理大数据量的查询场景。
- datasource:数据源模块,其中包含了 MyBatis 自定义的一款简易的数据源。
- exceptions:定义了常用的异常。
- executor:执行器模块,承载了 MyBatis 的核心执行流程,主要功能包括:Statement 创建、SQL 参数拼接、动态参数绑定、SQL 语句执行、结果集解析等。
- io:资源文件读取模块,用于定位和加载 MyBatis 相关的配置信息。
- jdbc:提供了操作原生 JDBC 的一些工具类。
- lang:这个包只包含了2个注解:
@UsesJava7
、@UsesJava8
,主要是用于标识类、方法等元素的 JDK 实现版本。 - logging:日志模块,MyBatis 自定义了统一的日志级别,饼整合了多种主流的第三方日志框架。
- mapping:映射模块,提供了配置文件与实体对象的映射功能,包括 Mapper 映射、参数映射、结果集映射等。
- parsing:字符串解析工具包,解析 SQL 语句中
$
、#
诸如此类的占位符,并生成 SQL 语句。 - plugin:插件模块,基于动态代理模式实现功能的扩展。著名的分页插件 PageHelper 就是基于 plugin 模块实现的。
- reflection:反射模块,是对 Java 底层的反射机制的二次封装,并提供了一系列的易用的反射工具类。
- scripting:动态 SQL 支持,mapper 配置文件中
if
、where
等 SQL 标签的功能就是基于此实现的。 - session:会话核心模块,实现了
SqlSession
的功能。 - transaction:事务模块,MyBatis 基于原生 JDBC 实现了基础的事务功能。
- type:类型处理模块,内置了一系列的 数据库类型 <-> Java 类型的转换器。
功能架构
介绍完了 MyBatis 的工程结构之后,我们一起看一下它的整体功能架构。按照业内主流的共识,MyBatis 的功能可以按照以下层次划分:
- 基础支撑层:主要面向底层技术,提供了一系列业务无关的通用能力,对核心处理层提供支持。基础支撑层的很多组件都可以单独拿出来放在我们自己的项目里使用。
- 核心处理层:MyBatis 在原生 JDBC 的基础上进行了高度的封装与抽象,提取了配置解析、SQL 解析、参数映射、SQL 执行和结果集映射等几大核心功能,并开发了插件机制解决扩展性的问题。
- 接口层:对外统一暴露了
SqlSession
和Mapper
接口进行数据库操作,屏蔽了底层的实现细节,大大简化了数据访问功能的开发流程。
门面模式 Facade Pattern
从 MyBatis 的整体架构来看,它的结构类似于门面模式,SqlSession
就相当于一个 Facade,内部聚合了 MyBatis 核心处理层的各个组件,来实现对数据库的各种操作,而对外屏蔽了复杂的逻辑处理,仅保留简单的 API 供客户端使用。这样一来,客户端无需关心 MyBatis 内部的实现细节,减少了用户的理解和学习成本。
(图片来源:https://refactoring.guru/design-patterns/facade)