MyBatis 执行器概述与源码解析

标签(空格分隔): Mybatis


执行器概述

  • 就想tomcat一样,Mybatis同样存在执行器,不过没有tomcat执行器那么复杂。
  • 执行器提供了查询,修改,提交事务,回滚事务,清理一级缓存,FlashStatement接口。
  • 一个执行器对应一个SqlSession,由Configuration创建。
  • Mybatis的执行器采用了委托模式设计,BaseExecutor、SimpleExecutor、ReuseExecutor、CachingExecutor是其实现类。CachingExecutor持有一个delegate对象,由它来实现执行器核心功能。
  • CachingExecutor在BaseExecutor基础上实现了缓存功能。
  • 简单来说Executor实现了与数据库的交互。

源码解析

  • 我们先来看下Mybatis创建Executor的过程

Mybatis 创建过程

执行过程: openSessionFromDataSource是openSession()内部的一个子方法, Mybatis在创建SqlSession的时候,new了一个Executor并把它放入了DefaultSqlSession中,我们也可以这样理解一个SqlSession持有一个Executor。执行器和数据库连接池在这里是没有关联的。

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      final Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

其中的 openSessionFromDataSource 中的 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;
  }

newExecutor 方法在Configuration中 , 根据executorType的类型来判断是生成BatchExecutor还是ReuseExecutor、SimpleExecutord
,cacheEnabled表示是否启用二期缓存。CachingExecutor中存在一个delegate委托对象,存有真实的执行器对象,interceptorChain是拦截器责任链,Executor 在pluginAll方法中做了转换,最后的executor是一个代理对象。
PS: 执行器、拦截器、缓存是Mybatis最重要的三部分。

下面是Mybatis执行器类图, 从下图可以看出执行器采用了委派模式。
Mybatis 执行器类图

猜你喜欢

转载自www.cnblogs.com/tamguo/p/11230222.html