关于前端:聊聊Mybatis的Executor之CachingExecutor

41次阅读

共计 2226 个字符,预计需要花费 6 分钟才能阅读完成。

聊聊 Mybatis 的 Executor 之 CachingExecutor
CachingExecutor

先看一下 CachingExecutor 类:

public class CachingExecutor implements Executor {

  private final Executor delegate;

  @Override
  public int update(MappedStatement ms, Object parameterObject) throws SQLException {flushCacheIfRequired(ms);
    return delegate.update(ms, parameterObject);
  }

CachingExecutor 的成员变量有个 Executor 实例,这显然是个 装璜器模式,这的类就是在其余 Executor 实例的办法进行了 flushCacheIfRequired(), 也就是刷新缓存,所以这个类在其余类上增加了缓存的性能,从 query()办法中也能看出先查找缓存,缓存没有再进行调用 Executor 实例的 query()进行数据的查问
二级缓存

这里的缓存是二级缓存,咱们通过它的 query()办法具体看一下二级缓存的逻辑:

@Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
      throws SQLException {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) {list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
          tcm.putObject(cache, key, list);
        }
        return list;
      }
    }
    return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }
获取二级缓存对象
如果对象不为空,表明开启了二级缓存,依据 select 标签的 flushCache 配置决定是否清空二级缓存,将其设置为 true 后,只有语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。而后检测 select 标签的 useCache 属性,将其设置为 true 后,将会导致本条语句的后果被二级缓存缓存起来,默认值:对 select 元素为 true
调用 TransactionalCacheManager 的 getObject()办法获取二级缓存
如果二级缓存为空就查询数据库,并把后果写入缓存中
最初返回 list

从代码中能够看出 TransactionalCacheManager 治理着缓存,他有个成员变量是 map 汇合:Map<Cache, TransactionalCache> transactionalCaches = new HashMap<>();

获取缓存的办法是先获取到 map 中的 TransactionalCache 对象,再调用 TransactionalCache 的 getObject(key)办法,那咱们须要重点看一下 TransactionalCache 类了
事务缓存类 TransactionalCache

TransactionalCache 实现了 Cache 接口,用来记录事务中的二级缓存的数据

public class TransactionalCache implements Cache {
  private final Map<Object, Object> entriesToAddOnCommit;

  @Override
  public void putObject(Object key, Object object) {entriesToAddOnCommit.put(key, object);
  }

}

entriesToAddOnCommit 是用来赞存二级缓存中的数据的,也是说在调用查询方法的时候,只是把二级缓存的数据缓存到 entriesToAddOnCommit 这个 map 汇合中,在调用 CachingExecutor 的 commit()办法的时候,才会遍历汇合把数据保留到二级缓存 Cache 中

@Override
  public void commit(boolean required) throws SQLException {delegate.commit(required);
    tcm.commit();}

总结

对于 Executor 的 CachingExecutor 实现类就说这么多,它的作用就是实现二级缓存的,由它的成员变量 TransactionalCacheManager 来进行治理二级缓存的数据,值得一提的是,二级缓存数据真正的提交是在事务提交之后进行,这能防止出现脏读景象

正文完
 0