CachingExecutor 和 BaseExecutor 裏的 query

CachingExecutor

  @Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
	//獲取sql語句信息,包括佔位符,參數等信息
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    //拼裝緩存的key值
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }
  @Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
      throws SQLException {
	//從MappedStatement中獲取二級緩存
    Cache cache = ms.getCache();
    //如果配置了二級緩存
    if (cache != null) {
      flushCacheIfRequired(ms);
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, boundSql);
        @SuppressWarnings("unchecked")
        List<E> list = (List<E>) tcm.getObject(cache, key);//從二級緩存中獲取數據
        if (list == null) {
          //二級緩存爲空,纔會調用BaseExecutor.query
          list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
          tcm.putObject(cache, key, list); // issue #578 and #116
        }
        return list;
      }
    }
    return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

BaseExecutor

上面的 query 會到下面這個方法來

@Override
  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) {//檢查當前executor是否關閉
      throw new ExecutorException("Executor was closed.");
    }
    if (queryStack == 0 && ms.isFlushCacheRequired()) {//非嵌套查詢,並且FlushCache配置爲true,則需要清空一級緩存
      clearLocalCache();
    }
    List<E> list;
    try {
      queryStack++;//查詢層次加一
      list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;//從緩存拿
      if (list != null) {
    	 //針對調用存儲過程的結果處理
        handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
      } else {
    	 //緩存未命中,從數據庫加載數據
        list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
      }
    } finally {
      queryStack--;
    }


    if (queryStack == 0) {
      for (DeferredLoad deferredLoad : deferredLoads) {//延遲加載處理
        deferredLoad.load();
      }
      // issue #601
      deferredLoads.clear();
      if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {//如果當前sql的一級緩存配置爲STATEMENT,查詢完既清空一集緩存
        // issue #482
        clearLocalCache();
      }
    }
    return list;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章