Mybatis
的整体架构分为三层,分别是基础支持层、核心处理层和接口层。基础支持层为核心处理层的功能提供了良好的支撑。

# 一、接口层
在不与Spring
集成的情况下,使用MyBatis
执行数据库的操作主要如下:
InputStream is = Resources.getResourceAsStream("myBatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
sqlSession = factory.openSession();
2
3
4
SqlSession
是MyBatis
核心接口之一,能够让你执行命令,获取映射,管理事务。该接口中定义了MyBatis
暴露给应用程序调用的API
,也就是上层应用与MyBatis
交互的桥梁。接口层在接收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。MyBatis
提供了两个SqlSession
接口的实现,如下,这里使用工厂模式,其中最常用的是DefaultSqlSession
实现。

package org.apache.ibatis.session;
import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;
public interface SqlSession extends Closeable {
// 定位到具体的SQL,返回值为查询结果对象
<T> T selectOne(String statement);
// 定位到具体的SQL,传入参数
<T> T selectOne(String statement, Object parameter);
// 查询结果会有多条返回记录
<E> List<E> selectList(String statement);
// 同上
<E> List<E> selectList(String statement, Object parameter);
// 返回结果为Map
<K, V> Map<K, V> selectMap(String statement, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
// 返回游标对象
<T> Cursor<T> selectCursor(String statement);
<T> Cursor<T> selectCursor(String statement, Object parameter);
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
// 查询结果有此处指定的ResultHandler 对象处理
void select(String statement, Object parameter, ResultHandler handler);
void select(String statement, ResultHandler handler);
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
// 执行插入语句
int insert(String statement);
int insert(String statement, Object parameter);
// 执行修改语句
int update(String statement);
int update(String statement, Object parameter);
// 执行删除语句
int delete(String statement);
int delete(String statement, Object parameter);
// 提交事务
void commit();
void commit(boolean force);
// 回滚事务
void rollback();
void rollback(boolean force);
// 刷新到数据库
List<BatchResult> flushStatements();
// 关闭当前session
@Override
void close();
// 清空缓存
void clearCache();
// 获取Configuration 对象
Configuration getConfiguration();
// 获取 type 对应的mapper 对象
<T> T getMapper(Class<T> type);
// 获取对应的数据库连接
Connection getConnection();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
DefaultSqlSession
中的核心字段的含义:使用了策略模式,DefaultSqlSession
扮演了Context
的角色,而将所有数据库相关的操作全部封装到Executor
接口实现中,并通过executor
字段选择不同的Executor
实现。
private final Configuration configuration;// Configuration 配置对象
private final Executor executor; //底层以来的 Executor
private final boolean autoCommit; //是否自动提交事务
private boolean dirty; //当前缓存中是否有脏数据
private List<Cursor<?>> cursorList; //统一关闭游标对象
2
3
4
5
# 二、核心处理层
在核心处理层中实现了MyBatis
的核心处理流程,其中包括MyBatis
的初始化以及完成一次数据库操作的全部流程,如下:
【1】配置解析:在MyBatis
初始化过程中,会加载mybatis-config.xml
配置文件、映射配置文件以及Mapper
接口中的注解信息,解析后的配置信息会形成相应的对象并保存到Configuration
对象中。例如,定义的<resultMap>
节点会被解析成ResultMap
对象,<result>
节点会被解析成ResultMapping
对象。之后,利用该Configuration
对象创建SqlSessionFactory
对象。待MyBatis
初始化之后,开发人员可以通过初始化得到SqlSessionFactory
创建SqlSession
对象并完成数据库操作。

MyBatis
层级结构各个组件的介绍:
【1】SqlSession
:它是MyBatis
核心API
,主要用来执行命令,获取映射,管理事务。接收开发人员提供Statement Id
和参数。并返回操作结果。
【2】Executor
:执行器,是MyBatis
调度的核心,负责 SQL 语句的生成以及查询缓存的维护。
【3】StatementHandler
: 封装了JDBC Statement
操作,负责对JDBC Statement
的操作,如设置参数、将Statement
结果集转换成 List
集合。
【4】ParameterHandler
: 负责对用户传递的参数转换成JDBC Statement
所需要的参数。
【5】ResultSetHandler
: 负责将JDBC
返回的ResultSet
结果集对象转换成List
类型的集合。
【6】TypeHandler
: 用于Java
类型和JDBC
类型之间的转换。
【7】MappedStatement
: 动态SQL
的封装
【8】SqlSource
: 表示从XML
文件或注释读取的映射语句的内容,它创建将从用户接收的输入参数传递给数据库的SQL
。
【9】Configuration
: MyBatis
所有的配置信息都维持在Configuration
对象之中。
# 三、基础支持层
【1】反射模块: 该模块对Java
原生的反射进行了良好的封装,提供了更加简洁的API
,方便上层调用,并且对反射操作进行了一系列优化,例如缓存类的元数据,提高了反射操作的性能。
【2】类型转换模块: MyBatis
为简化配置文件提供了别名机制,该机制是类型转化模块的主要功能之一。另一个功能是JDBC
类型与 Java
类型之间的转换,该功能在为SQL
语句绑定实参以及映射查询结果集时都会涉及。在为SQL
语句绑定实参时,会将数据由Java
类型转化成JDBC
类型;而在映射结果集时,会将数据由JDBC
类型转换成Java
类型。
【3】日志模块: 无论在开发测试环境中,还是在线上生产环境中,日志在整个系统中的地位都是非常重要的。良好的日志功能可以帮助开发人员快速定位bug
,也可以帮助运维人员快速定位性能瓶颈问题。目前Java
世界中存在很多优秀的日志框架,例如Log4j
、slf4j
等。MyBatis
作为一个设计优良的框架,除了提供详细的日志输出信息,还要能够集成多种日志框架。
【4】资源加载模块: 资源加载模块主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其它资源资源文件的功能。
【5】解析器模块: 对XPath
进行封装,为MyBatis
初始化时解析mybatis-config.xml
配置文件以及映射配置文件提供支持,为处理动态SQL 语句中的占位符提供支持。
【6】数据源模块: 开源的数据源都提供了丰富的功能,比如连接池功能,检测连接状态等。选择优秀的数据源组件对于提升ORM
框架乃至整个应用的性能都有非常主要的帮助。MyBatis
自身提供了相应的数据源实现,也提供了与第三方数据源集成的接口。
【7】事务管理: MyBatis
对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。在很多场景中,MyBatis
与Spring
框架集成,并由Spring
框架管理事务。
【8】缓存模块: 优化性能时,优化数据库性能是非常重要的一个环节,而添加缓存则是优化数据库时最有效的手段之一。合理地使用缓存可以将一部分数据库请求拦截在缓存这一层,能够减少相当一部分数据库的压力。MyBatis
提供了一级缓存和二级缓存,而这两级缓存都是依赖于基础支持层中的缓存模块实现的。MyBatis
中自带的这两级缓存与MyBatis
以及整个应用是运行在同一个JVM
中的,共享同一块堆内存。如果这两级缓存中的数据量较大, 则可能影响系统中其他功能的运行,所以当需要缓存大量数据时,优先考虑使用Redis
、Memcache
等缓存产品。
【9】Binding 模块: 在调用SqlSession
相应方法执行数据库操作时,需要指定映射文件中定义的SQL
节点,如果出现拼写错误,我们只能在运行时才能发现相应的异常。为了尽早发现这种错误,MyBatis
通过Binding
模块将用户自定义的Mapper
接口与映射配置文件关联起来,系统可以通过调用自定义Mapper
接口中的方法执行相应的SQL
语句完成数据库操作,从而避免上述问题。开发人员无需编写自定义Mapper
接口的实现,MyBatis
会自动为其创建动态代理对象。在有些场景中,自定义Mapper
接口可以完全代替映射配置文件,但有的映射规则和SQL
语句的定义还是写在映射配置文件中比较方便,例如动态SQL
语句的定义。
← MyBatis 源码 磁盘IO 基本常识 →