SqlSession对象之Executor
Executor是Mybatis的一个核心接口,每一个SqlSession对象都会拥有一个Executor(执行器对象);这个执行对象负责[增删改查]的具体操作,我们可以简单的将它理解为JDBC中Statement的封装版。它的代码如下:
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
int update(MappedStatement ms, Object parameter) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
List<BatchResult> flushStatements() throws SQLException;
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
boolean isCached(MappedStatement ms, CacheKey key);
void clearLocalCache();
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
Transaction getTransaction();
void close(boolean forceRollback);
boolean isClosed();
void setExecutorWrapper(Executor executor);
}
一、Executor的继承结构
Executor的类图如下所示:

Executor是一个接口,主要有两个实现类:分别是BaseExecutor和CachingExecutor。
1、BaseExecutor类
BaseExecutor是一个抽象类,这种通过抽象类实现接口的方式是适配器设计模式的体现,主要用于方便次一级子类对接口中方法的实现。BaseExecutor主要有三个实现类SimpleExecutor、ReuseExecutor和BatchExecutor。三个实现类分别对应executor对Statement对象管理方案。
- 简单方案:一个Statement接口对象只执行一次,执行完毕就会Statement接口对象进行销毁。对应SimpleExecutor,被称为简单执行器,是MyBatis中默认使用的执行器,每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象(可以是Statement或PrepareStatement对象)。
- 可重用方案:对应ReuseExecutor,被称为可重用执行器,重用指的是重复使用Statement,它会在内部利用一个Map把初始化的Statement都缓存起来,每次在执行一条SQL语句时,它都会去判断之前是否存在基于该SQL缓存的Statement对象,存在而且之前缓存的Statement对象对应的Connection还没有关闭的时候就继续用之前的Statement对象,否则将初始化一个新的Statement对象,并将其缓存起来。因为每一个新的SqlSession都有一个新的Executor对象,所以我们缓存在ReuseExecutor上的Statement的作用域是同一个SqlSession。
- 批量处理方案:对应BatchExecutor,称为批处理执行器,用于将多个Statement对应的SQL语句,交给一个Statement对象一次输送到数据库,进行批处理操作。
2、CachingExecutor类
CachingExecutor称为缓存执行器,MyBatis框架默认情况下使用执行器缓存执行器,可以提高查询效率,先从缓存中获取查询结果,存在就返回,不存在,再委托给Executor delegate去数据库取,delegate可以是SimpleExecutor、ReuseExecutor、BatchExecutor中任意一个。
二、Executor对象初始化
Executor的初始化是在SqlSessionFactory调用openSession方法期间初始化的,首先看一下SqlSessionFactory中的方法,具体代码如下:
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
Configuration getConfiguration();
}
由代码可见,SqlSessionFactory中的openSession方法分为两类:带ExecutorType和不带ExecutorType的,此外每个类型还有四种,这里采用了重载的方法,方法名称相同,参数列表不同。下面进入到SqlSessionFactory的实现类DefaultSqlSessionFactory中查看openSession()d的实现,代码如下:
@Override
public SqlSession openSession(ExecutorType execType) {
return openSessionFromDataSource(execType, null, false);
}
@Override
public SqlSession openSession(TransactionIsolationLevel level) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
}
...
通过查看代码发现,所有的openSession方法都会走向openSessionFromDataSource方法中,openSessionFromDataSource的代码如下:
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException e) {
autoCommit = true;
}
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
主要看其中的两行代码:
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
这两行代码先产生executor,再产生了DefaultSqlSession对象,也验证了前面所说的执行器的初始化是在SqlSession初始化之前进行的。下面我们继续查看执行器的初始化过程,它的初始化是由Configuration完成的,初始化Executor的方法newExecutor()的代码如下所示:
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
由代码可见:首先判断初始化ExecutorType是否为空,若不为空,则默认执行器为SimpleExecutor。而这里的ExecutorType类型则是由openSession方法传入的,因而SqlSessionFactory中没有ExecutorType参数的openSession()则默认为SimpleExecutor。此外关注以下代码:
protected boolean cacheEnabled = true;
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
这里是初始化CachingExecutor执行器,可见默认情况下CachingExecutor执行器是开启的。
三、ExecutorType的选择
ExecutorType是枚举类型,其代码如下:
public enum ExecutorType {
SIMPLE, REUSE, BATCH
}
ExecutorType的枚举值分别对应三种执行器类型:简单执行器、可重用执行器、批量执行器。
ExecutorType的类型选择,有两种方式对其进行赋值。
1、<settings>标签设置
通过<settings>标签来设置当前工程中所有SqlSession对象使用的默认Executour。

2、openSession方法指定
通过SqlSessoinFactory中openSession方法来指定具体的SqlSession使用的执行器。

SqlSession对象之Executor的更多相关文章
- SqlSession对象之StatementHandler
上一篇讲了SqlSession对象中的Executor,接下来将对SqlSession的另一个对象StatementHandler进行讲解. 一.StatementHandler介绍 Statemen ...
- MyBatis 源码分析——SqlSession接口和Executor类
mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用.可以说SqlSession接口实例是开发过程中打交道最多的一个类.即是DefaultSqlSession类.如果笔者记得 ...
- mybatis的两个核心对象SqlSessionFactory和SqlSession对象
mybatis的两个核心对象SqlSessionFactory和SqlSession对象 参见:https://www.cnblogs.com/wxdestiny/p/9743686.html
- 对 Service中sqlsession对象的优化
在本线程中添加object数据,必须在本线程中才能获取出来..其他线程获取不到. public class Test { public static void main(String[] args) ...
- SqlSession接口和Executor
mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用.可以说SqlSession接口实例是开发过程中打交道最多的一个类.即是DefaultSqlSession类.如果笔者记得 ...
- 使用ThreadLocal管理Mybatis中SqlSession对象
转自http://blog.csdn.net/qq_29227939/article/details/52029065 public class MybatisUtil { private stati ...
- SqlSession对象之ResultSetHandler
ResultSetHandler是Mybatis中的另一重要接口,它的代码如下所示: public interface ResultSetHandler { <E> List<E&g ...
- SqlSession对象之ParameterHandler
上一篇讲了StatementHandler,其中有ParameterHandler(参数处理器)是在StatementHandler被创建时被创建的.下面对ParameterHandler进行说明.其 ...
- 深入浅出MyBatis-Sqlsession
前面的章节主要讲mybatis如何解析配置文件,这些都是一次性的过程.从本章开始讲解动态的过程,它们跟应用程序对mybatis的调用密切相关.本章先从sqlsession开始. 创建 正如其名,Sql ...
随机推荐
- [BZOJ2738]矩阵乘法(整体二分+二维树状数组)
整体二分+二维树状数组. 好题啊!写了一个来小时. 一看这道题,主席树不会搞,只能用离线的做法了. 整体二分真是个好东西,啥都可以搞,尤其是区间第 \(k\) 大这种东西. 我们二分答案,然后用二维树 ...
- 牛客第二场 C.message(计算几何+二分)
题目传送:https://www.nowcoder.com/acm/contest/140/C 题意:有n个云层,每个云层可以表示为y=ax+b.每个飞机的航线可以表示为时间x时,坐标为(x,cx+d ...
- 不能将 CHECK_POLICY 和 CHECK_EXPIRATION 选项设为 OFF (关)
数据库用户信息死活无法修改..老是出现错误当 MUST_CHANGE 为 ON (开)时,不能将 CHECK_POLICY 和 CHECK_EXPIRATION 选项设为 OFF (关). (Micr ...
- mac下安装rzsz
1.先安装item2,item2 市类似mac风格的终端 item2 下载地址,http://iterm2.com/downloads.html,下载后解压缩就能运行 2.Install Homebr ...
- Android:异步处理之Handler+Thread的应用(一)
前言 很久很久以前就听说了,每一个android的应用程序都会分别运行在一个独立的dalvik虚拟机进程中,而在每个虚拟机在启动时会运行一个UI主线程(Main Thread),而为啥叫UI主线程而不 ...
- 利用:before和:after伪类制作CSS3 圆形按钮 含demo
要求 必备知识 基本了解CSS语法,初步了解CSS3语法知识. 开发环境 Adobe Dreamweaver CS6 演示地址 演示地址 预览截图(抬抬你的鼠标就可以看到演示地址哦): 制作步骤: 一 ...
- PHP多进程系列笔记(一)
本系列文章将向大家讲解pcntl_*系列函数,从而更深入的理解进程相关知识. PCNTL在PHP中进程控制支持默认是关闭的.您需要使用 --enable-pcntl 配置选项重新编译PHP的 CGI或 ...
- JVM几种垃圾回收器介绍
整理自:http://www.cnblogs.com/lspz/p/6397649.html 一.如何回收? 1.1 垃圾收集算法: (1)标记-清除(Mark-Sweep)算法 这是最基础的算法,就 ...
- T-SQL 分布式查询
--返回本地服务器中定义的链接服务器列表. EXEC sys.sp_linkedservers /* 创建或更新 SQL Server 本地实例上的登录名与远程服务器中安全帐户之间的映射. 当用户登录 ...
- PowerBuilder编程新思维4:钩挂(界面美化与DirectUI)
<第二部分 Outside> PowerBuilder编程新思维4:钩挂(界面美化与DirectUI) PB的界面由于其封闭性,一直以来都是最大的弱项.自PB9.0开放了PBNI接口后,开 ...