一、主要职责
基本功能:改、查
缓存维护:一级缓存
事务管理:提交、回滚、关闭、批处理刷新
辅助功能:提交,关闭执行器,批处理刷新(flushStatements)
二、类结构图
Executor顶层接口为基本方法的定义
-
BaseExecutor(基础执行器)
将三个实现的执行器共同部分抽象到基础执行器中,主要处理顶层接口的事务管理和一级缓存,query和update方法会先处理完一级缓存逻辑后,抽象方法doQuery/doUpdate为子类真正的执行逻辑。
-
SimpleExecutor(简单执行器,默认)
每次sql请求都会编译两次执行两次
==> Preparing: select * from t00_name where id=?
==> Parameters: 1(Long)
<== Columns: id, name
<== Row: 1, name
<== Total: 1
==> Preparing: select * from t00_name where id=?
==> Parameters: 1(Long)
<== Columns: id, name
<== Row: 1, name
<== Total: 1
-
ReuseExecutor(可重用执行器)
相同的sql会仅编译一次,执行若干次
==> Preparing: select * from t00_name where id=?
==> Parameters: 1(Long)
<== Columns: id, name
<== Row: 1, name
<== Total: 1
==> Parameters: 1(Long)
<== Columns: id, name
<== Row: 1, name
<== Total: 1
-
BatchExecutor(批处理执行器)
相同且连续的sql编译会进行合并
==> Preparing: update t00_name set name = ? where id = ?
==> Parameters: test(String), 1(Long)
==> Parameters: test(String), 1(Long)
-
CachingExecutor(二级缓存执行器)
二级缓存可以通过参数控制开启关闭,使用装饰者模式单独抽离出来,职责更加的单一。在调用的时候先去调用二级缓存,二级缓存中有一个属性Executor delegate指向BaseExecutor,在不改变原有类结构和继承的基础上实现对功能的增强
Cache Hit Ratio [com.lr.mybatis.NameMapper]: 0.0
==> Preparing: select * from t00_name where id=?
==> Parameters: 1(Long)
<== Columns: id, name
<== Row: 1, test
<== Total: 1
Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@21d08148]
Cache Hit Ratio [com.lr.mybatis.NameMapper]: 0.5
三、默认执行器
当我们从SqlSessionFactory中获取一个session的时候,默认就已经初始化好了执行器,下面追溯一下代码
默认为DefaultSqlSessionFactory,里面有各种openSession的重载,不过最后都会指向两个方法openSessionFromDataSource或者openSessionFromConnection,下面我们先看一下
openSessionFromDataSource
最终都会调用到
final Executor executor = configuration.newExecutor(tx, execType);
那么我们只需要着重关注一下这个方法的逻辑即可
protected boolean cacheEnabled = true;
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
首先我们可以看到类的两个变量会有默认值,一个默认开启二级缓存,一个默认执行器为SimpleExecutor,上面的方法内容就比较简单不不过说明了