1.Executor介绍:

Executor是mybatis的核心接口之一,其中定义了数据库操作的基本方法,它的子类结构图如下:这这张关系图中,涉及到了模板方法模式和装饰器模式。BaseExecutor是一个抽象父类,定义了一级缓存和事务相关的公共的固定不变的方法,同时定义了doUpdate,doQuery等抽象方法,这些抽象方法是在BaseExecutor的四个子类中实现的。这里用到了模板方法模式。对于CachingExecutor这个类,它为Executor提供了二级缓存的功能,它是一个装饰类,被装饰的目标类是BaseExecutor的四个子类,比如是SimpleExecutor,所以这里用到了装饰器模式。

2.源码分析:

2.1 Executor源码:

public interface Executor {ResultHandler NO_RESULT_HANDLER = null;// 执行update,insert,delete三种类型的SQLint update(MappedStatement ms, Object parameter) throws SQLException;// 执行select类型的SQL <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;
// 批量执行SQLList<BatchResult> flushStatements() throws SQLException; // 事务提交 void commit(boolean required) throws SQLException;// 事务回滚void rollback(boolean required) throws SQLException;// 创建一级缓存中使用到的CacheKey对象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);}

2.2 BaseExecutor

BaseExecutor是一个实现了Executor的抽象类,它实现了Executor的大部分方法,比如:一级缓存管理和事务管理的基本功能,它的四个子类只需要实现doQuery,doUpdate等抽象方法来完成数据库的相关操作。

public abstract class BaseExecutor implements Executor {private static final Log log = LogFactory.getLog(BaseExecutor.class);protected Transaction transaction;  // transaction对象protected Executor wrapper; // 封装的executor对象 protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;protected PerpetualCache localCache; // 一级缓存 用于缓存该Executor对象查询结果集映射得到的结果对象protected PerpetualCache localOutputParameterCache;protected Configuration configuration;protected int queryStack = 0;private boolean closed;  // 获取transaction对象public Transaction getTransaction() {if (closed) throw new ExecutorException("Executor was closed.");return transaction;}public int update(MappedStatement ms, Object parameter) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());if (closed) throw new ExecutorException("Executor was closed.");clearLocalCache();return doUpdate(ms, parameter);}
  // 批量执行多条缓存的SQLpublic List<BatchResult> flushStatements(boolean isRollBack) throws SQLException {if (closed) throw new ExecutorException("Executor was closed.");return doFlushStatements(isRollBack);}public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {BoundSql boundSql = ms.getBoundSql(parameter);CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);return query(ms, parameter, rowBounds, resultHandler, key, boundSql);}  // 先查询一级缓存,如果未命中,则再查询数据库@SuppressWarnings("unchecked")public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());if (closed) throw new ExecutorException("Executor was closed.");if (queryStack == 0 && ms.isFlushCacheRequired()) {clearLocalCache();}List<E> list;try {queryStack++;list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;if (list != null) {handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);} else {// 此处会调用在子类中实现的doQuery方法,默认的子类是SimpleExecutorlist = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {queryStack--;}if (queryStack == 0) {for (DeferredLoad deferredLoad : deferredLoads) {deferredLoad.load();}deferredLoads.clear(); // issue #601if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {clearLocalCache(); // issue #482
      }}return list;}

  // 事务提交public void commit(boolean required) throws SQLException {if (closed) throw new ExecutorException("Cannot commit, transaction is already closed");clearLocalCache();flushStatements();if (required) {transaction.commit();}}  // 事务回滚public void rollback(boolean required) throws SQLException {if (!closed) {try {clearLocalCache();flushStatements(true);} finally {if (required) {transaction.rollback();}}}}  // 需要在子类中实现的update操作protected abstract int doUpdate(MappedStatement ms, Object parameter)throws SQLException;protected abstract List<BatchResult> doFlushStatements(boolean isRollback)throws SQLException; // 需要在子类中实现的query操作protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)throws SQLException;}}

由上面的query方法可知,BaseExecutor提供了一级缓存的查询功能,如果一级缓存未命中,则再会调用在它的子类中实现的doQuery方法,默认的子类是SimpleExecutor。

2.3 SimpleExecutor

SimpleExecutor继承了BaseExecutor抽象类,它是最简单的Executor接口的实现。这里使用到了模板方法模式,一级缓存和事务管理等固定不变的操作封装到了BaseExecutor这个父类中,而update,query等与数据库交互的基本方法,都在子类中实现的。

public class SimpleExecutor extends BaseExecutor {public SimpleExecutor(Configuration configuration, Transaction transaction) {super(configuration, transaction);}
  // upate,insert,delete操作public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {Statement stmt = null;try {Configuration configuration = ms.getConfiguration();StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);stmt = prepareStatement(handler, ms.getStatementLog());return handler.update(stmt);} finally {closeStatement(stmt);}}// query操作public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {Statement stmt = null;try {Configuration configuration = ms.getConfiguration();   // 创建StatementHandler对象StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql); // 完成Statement的创建和初始化stmt = prepareStatement(handler, ms.getStatementLog()); // 调用StatementHandler.query方法,执行SQL语句,并通过ResultSetHandler完成结果集的映射return handler.<E>query(stmt, resultHandler);} finally {closeStatement(stmt);}}}

对于另外三个子类这里就不做分析了。接下来介绍CachingExecutor这个类

2.4 CachingExecutor

对于CachingExecutor,通过装饰器模式,为Executor增加了二级缓存的功能,接下来就对它的属性和主要方法做个分析:

2.4.1 属性:

  private Executor delegate; // 被装饰的类,也成为目标类private TransactionalCacheManager tcm = new TransactionalCacheManager(); // 用于管理Cahce和TransactionCache,也就是和二级缓存相关的

2.4.2 查询方法:

  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)throws SQLException {Cache cache = ms.getCache(); // 如果映射配置文件中配置了<cache/>,则此处cache!= nullif (cache != null) {flushCacheIfRequired(ms);// 查询节点的useCache配置以及是否是否使用了resultHandlerif (ms.isUseCache() && resultHandler == null) {ensureNoOutParams(ms, parameterObject, boundSql);@SuppressWarnings("unchecked")// 查询二级缓存List<E> list = (List<E>) tcm.getObject(cache, key);if (list == null) {// 如果二级缓存没有查询出结果,会调用封装的Executor对象的query方法,其中会先查询一级缓存,再执行数据库查询操作list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);tcm.putObject(cache, key, list); // issue #578. Query must be not synchronized to prevent deadlocks
        }return list;}}// 没有启动二级缓存,直接调用底层Executor执行数据库的查询操作return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}

 2.4.3 事务提交:

  public void commit(boolean required) throws SQLException {delegate.commit(required); // 调用底层的Executor提交事务tcm.commit(); // 遍历所有的TransactionCahce对象执行commit方法}

关于Executor就暂时说这么多吧,其实这些内容在其他文章中都有提到,这里不过是做一个简单的分类总结。

转载于:https://www.cnblogs.com/51life/p/9647428.html

Executor介绍相关推荐

  1. Mybatis的Executor介绍

    Mybatis中所有的Mapper语句的执行都是通过Executor进行的,Executor是Mybatis的一个核心接口,其定义如下.从其定义的接口方法我们可以看出,对应的增删改语句是通过Execu ...

  2. Mybatis源码分析之-Executor

      mybatis的源代码相对于spring的来说简单了很多,对于初学者,可以先了解了mybatis的源码后再去了解spring的源码,本文主要来分析下Executor的内容 Executor介绍   ...

  3. Executor详细介绍 打造基于Executor的Web服务器

    继续并发,貌似并发的文章很少有人看啊~哈~ 今天准备详细介绍java并发包下的Executor,以及Java提供了很多灵活的且极其方便的线程池的创建. 嗯,那就慢慢说,大家肯定都学过Socket,Ja ...

  4. Executor框架的介绍

    executor框架组成 任务: 包括被执行任务需要实现的接口:runnable和callable 任务的执行: 包括任务执行机制的核心接口Executor,以及继承自ExecutorExecutor ...

  5. sqoop架构_SQOOP架构的深入介绍

    sqoop架构 by Jayvardhan Reddy 通过杰伊瓦尔丹·雷迪(Jayvardhan Reddy) SQOOP架构的深入介绍 (An in-depth introduction to S ...

  6. ThreadPoolExecutor使用介绍

    private static ExecutorService exec = new ThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new Li ...

  7. Java基础篇:Executor框架

    文章目录 概述 Executor框架结构 Executor框架的使用示意图 `ThreadPoolExecutor`类介绍 `ThreadPoolExecutor` 类分析 推荐使用 `ThreadP ...

  8. Java基础系列--Executor框架(一)

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8393618.html 一.Executor框架介绍 Executor框架是JDK1.5之后 ...

  9. Spark Streaming实时计算框架介绍

    随着大数据的发展,人们对大数据的处理要求也越来越高,原有的批处理框架MapReduce适合离线计算,却无法满足实时性要求较高的业务,如实时推荐.用户行为分析等. Spark Streaming是建立在 ...

最新文章

  1. java查看内存地址_Java内存机制和内存地址
  2. 主瓣、栅瓣和旁瓣的定义
  3. MongoError: topology was destroyed解决方法
  4. 万年历java课程设计报告_java万年历课程设计报告2010
  5. nil slice 和 空 slice
  6. Microsoft Edge浏览器最新版已经换成开源Chromium引擎了,附官方下载地址
  7. 20万人仍然每天活跃在“死”掉的ofo APP上:这已变成一个返利应用
  8. Zxing二维码重复扫描,不退出。
  9. Jmeter压力测试实例
  10. 计算机远程怎么设置路由器,路由器远程登录设置方法
  11. ①读后感之《当我们谈论爱情时我们在谈论什么》┊(美)雷蒙德.卡佛
  12. 基本模块 time datetime randon os sys subprocess 打印进度条
  13. 详解EventBus实现原理
  14. win10打开软件提示无法成功完成操作 因为文件包含病毒
  15. STM32滤波电容个数和大小的确定
  16. sequoia 的详细安装步骤
  17. YYModel之字典/Json转模型
  18. Miniconda的安装与使用及pip在conda环境中的安装
  19. 从电阻丝印读取电阻阻值
  20. 半导体分立器件静态参数测试系统 DCT1401 天光测控

热门文章

  1. 人脸识别如何在大型银行中大规模商用?
  2. struts2中用户登陆验证的常用方法
  3. 网页爬虫 html知识,python爬虫
  4. Vivado中TCL的使用
  5. 计算机三级考试网络技术怎么复习,2017计算机三级考试的三大复习阶段(网络技术为例)...
  6. php如何删除数据库中的数据库文件夹,学习猿地-php数据库如何删除数据
  7. Windows XP下如何设置电脑定时关机
  8. Linux下软件安装方法汇总
  9. pythorch创建简单的神经网络源码
  10. zabbix3.2自动发现批量监控redis端口状态