美文网首页
Mybatis-缓存

Mybatis-缓存

作者: 01010100 | 来源:发表于2018-02-26 19:33 被阅读0次

    缓存

    当我们发起一次数据库查询时,如果启用了二级缓存的话,MyBatis 首先会先从二级缓存中检索查询结果,如果缓存不命中则会继续检索一级缓存,只有在这两层缓存都不命中的情况下才会查询数据库,最后会以数据库返回的结果更新一级缓存和二级缓存。

    一级缓存是基于 sqlSession 的,而 二级缓存是基于 mapper文件的namespace

    也就是说多个sqlSession可以共享一个mapper中的二级缓存区域,并且如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中

    先看看创建Executor的过程:

    // 创建执行器(Configuration.newExecutor)

    public Executor newExecutor(Transaction transaction, ExecutorType 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的Cache包装类对象 executor = new CachingExecutor(executor); } executor = (Executor) interceptorChain.pluginAll(executor); return executor;}

    一级缓存

    BaseExecutor 是一个抽象类,实现了 Executor 接口中声明的所有方法。BaseExecutor 抽象类引入了一级缓存支持,在相应方法实现中增加了对一级缓存的操作,因此该类的所有派生类都具备一级缓存的特性。一级缓存比较简单,具体实现是PerpetualCache

    二级缓存

    由上面创建执行器可以看出,二级缓存是需要单独配置的。

    需要以下两步:全局配置:mapper配置: 多个Mapper共用一个Cache缓存对象(使用节点配置)详细实现:CachingExecutor其实是个代理模式,所有操作都是通过deleget来完成的。private Executor delegate;只有查询缓存是自己实现的。缓存策略:先看缓存的构建:

    CacheBuilder

    public Cache build() {

    setDefaultImplementations();

    Cache cache = newBaseCacheInstance(this.implementation, this.id);

    ..

    return cache;

    }

    setDefaultImplementations:

    this.implementation = PerpetualCache.class;

    if (this.decorators.isEmpty())

        this.decorators.add(LruCache.class);

    }

    可以看出二级缓存的默认实现也是PerpetualCache,另外缓存策略是通过装饰器模式来实现的,默认的缓存策略是LRU

    完整的一级缓存、二级缓存的工作,其中一级缓存的实现真正是通过BaseExecutor实现。

    相关文章

      网友评论

          本文标题:Mybatis-缓存

          本文链接:https://www.haomeiwen.com/subject/ctfuxftx.html