• Executor介绍


    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三种类型的SQL
      int 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;
    
    // 批量执行SQL List
    <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); }
    // 批量执行多条缓存的SQL
    public 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方法,默认的子类是SimpleExecutor list
    = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { queryStack--; } if (queryStack == 0) { for (DeferredLoad deferredLoad : deferredLoads) { deferredLoad.load(); } deferredLoads.clear(); // issue #601 if (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!= null
    if (cache != null) { flushCacheIfRequired(ms);
    // 查询节点的useCache配置以及是否是否使用了resultHandler
    if (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就暂时说这么多吧,其实这些内容在其他文章中都有提到,这里不过是做一个简单的分类总结。

  • 相关阅读:
    053532
    053531
    053530
    053529
    053528
    RTSP和RTMP的区别是什么?
    RTSP、RTMP和HTTP协议的区别
    在C#中实现视频播放器
    wpf下基于opencv实现视频播放器
    C#实现视频播放器(Vlc.DotNet)
  • 原文地址:https://www.cnblogs.com/51life/p/9647428.html
Copyright © 2020-2023  润新知