(四)Mybatis Executor接口实现方式--MyBatis源码解析

经过上一篇文章的我们应该对sqlsession的创建以及方法使用有所了解

  1. select类方法
  2. update/insert/delete方法
  3. commit()
  4. rollback()
  5. close()

接下来我们就来讲下sql的执行器是如何执行sql的,首先我们来普及下Executor,让大家对执行器稍微有点印象,让接下来的讲解更容易理解,不那么抽象。先让我们看两张图,刷个脸熟

  1. BaseExecutor为模板模式中的模板类。这个类在Executor接口实现中非常重要,其实现了Executor的大部分方法。他的子类只要实现三个方法即可,其中两个是doUpdate和doSelect方法,子类在实现这两个方法时直接操作数据库即可,其余的工作交由BaseExecutor完成。
  2. CachingExecutor是一个Executor的装饰器,给一个Executor增加了缓存的功能。

我们来看下Executor接口主要方法

public interface Executor {
   //执行update/insert/delete
  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;
  //以后有机会在分析 
  List<BatchResult> flushStatements() throws SQLException;
  //事务提交
  void commit(boolean required) throws SQLException;
  //事务回滚
  void rollback(boolean required) throws SQLException;
  //生成缓存的key
  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);
 
}

接下来我们再来看看BaseExcutor模板是怎么实现Executor的

BaseExecutor有两个主要的属性:事务及本地缓存

protected BaseExecutor(Configuration configuration, Transaction transaction) {
    //transaction,实现commit/rollback/close
    this.transaction = transaction;
    this.deferredLoads = new ConcurrentLinkedQueue<DeferredLoad>();
    //本地缓存,也就是一级缓存
    this.localCache = new PerpetualCache("LocalCache");
    this.localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache");
    this.closed = false;
    this.configuration = configuration;
    this.wrapper = this;
}

我们看下是如何查询和更新的

查询方法的实现
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, 
                                ResultHandler resultHandler) throws SQLException {
        BoundSql boundSql = ms.getBoundSql(parameter);
        CacheKey key = this.createCacheKey(ms, parameter, rowBounds, boundSql);
        return this.query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
更新操作的实现
public int update(MappedStatement ms, Object parameter) throws SQLException {
        ErrorContext.instance().resource(ms.getResource()).activity("executing an 
        update").object(ms.getId());
        if(this.closed) {
            throw new ExecutorException("Executor was closed.");
        } else {
            this.clearLocalCache();
            return this.doUpdate(ms, parameter);
        }
}
带缓存的查询实现
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds 
    rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws 
                                                                        SQLException {
        this.localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER);

        List list;
        try {
            list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
        } finally {
            this.localCache.removeObject(key);
        }

        this.localCache.putObject(key, list);
        if(ms.getStatementType() == StatementType.CALLABLE) {
            this.localOutputParameterCache.putObject(key, parameter);
        }

        return list;
}

和BaseExcutor平起平坐的还有一个执行器那就是CachingExecutor

具体数据库语句执行都是通过Excutor实现类去操作的,只是操作之前刷新本地缓存,和baseExcutor 区别不太大,感兴趣的可以下载源码看看
org.apache.ibatis.executor.CachingExecutor
public CachingExecutor(Executor delegate) {
    //操作数据库的动作都是由这个Executor来完成的。
    this.delegate = delegate;
    delegate.setExecutorWrapper(this);
}

猜你喜欢

转载自blog.csdn.net/ikownyou/article/details/81364975
今日推荐