/**
   * when executing a query operation 1. record this statement's id and it's corresponding Cache
   * Object into Global Caching Manager; 2. record this statement's id and
   *
   * @param invocation
   * @return
   * @throws Throwable
   */
  private Object processQuery(Invocation invocation) throws Throwable {
    Object result = invocation.proceed();
    if (cachingManager.isCacheEnabled()) {
      Object[] args = invocation.getArgs();
      MappedStatement mappedStatement = (MappedStatement) args[0];

      // 如果本条statementId表示的查询语句配置了 flushCache=true,则清空querCacheOnCommit缓存
      if (mappedStatement.isFlushCacheRequired()) {
        queryCacheOnCommit.clear();
      }
      // 如果本条statementId表示的查询语句配置了使用缓存,并且二级缓存不为空,则将StatementId
      // 和对应的二级缓存对象映射关系添加到全局缓存映射管理器中
      if (mappedStatement.isUseCache() && mappedStatement.getCache() != null) {
        cachingManager.appendStatementCacheMap(mappedStatement.getId(), mappedStatement.getCache());
      }

      Object parameter = args[1];
      RowBounds rowBounds = (RowBounds) args[2];
      Executor executor = (Executor) invocation.getTarget();
      BoundSql boundSql = mappedStatement.getBoundSql(parameter);

      // 记录本次查询所产生的CacheKey
      CacheKey cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
      queryCacheOnCommit.putElement(mappedStatement.getId(), cacheKey);
    }

    return result;
  }
 /**
  * when the sqlSession has been committed,rollbacked,or closed, session buffer query CacheKeys and
  * update Statement collections should be cleared.
  *
  * <p>当SqlSession 执行了commit()、rollback()、close()方法, Session级别的查询语句产生的CacheKey集合以及 执行的更新语句集合应该被清空
  */
 private synchronized void clearSessionData() {
   queryCacheOnCommit.clear();
   updateStatementOnCommit.clear();
 }