MyBatis 緩存實現原理


標簽(空格分隔): mybatis


緩存概述

  • mybatis存在一級緩存和二級緩存
  • 一級緩存在BaseExecutor中實現,二級緩存在CachingExecutor中實現。
  • mybatis緩存采用了裝飾器和委托模式。(LoggingCache、SynchronizedCache是其裝飾類)
  • 一級緩存和二級緩存都存放在PerpetualCache對象中,PerpetualCache持有一個Map<Object, Object> Cache屬性
    Key為CacheKey,Value為sql執行后的結果集。CacheKey 根據namespace、offset、limit、sql輸個屬性生成。
  • 二級緩存支持其他緩存介質接入。

立即開始

***Mapper.xml 配置中加入,這里啟用了二級緩存。

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
  • evication 表示緩存采用的淘汰策略,flushInterval表示緩存的刷新時間,size表示緩存數量到達多大時刷新,readOnly則表示緩存是否只讀。
  • 在mybatis初始化時會把mapper.xml解析成StatementMapper對象,StatementMapper維護一個cache對象,二級緩存是和StatementMapper綁定在一起的。

代碼

mybatis-cache

  • 從上面的包名和類名我們可以看出,mybatis的緩存采用了裝飾器模式。委托模式在CachingExecutor類中能看出來。

一級緩存

mybatis-baseexecutor-cache

  • 一級緩存在BaseExecutor類中實現,在152行中,如果返回結果不為空,並且能在localCache中get到數據,mybatis就不會再去查詢數據庫。 其中的localCache是一個PerpetualCache對象。

  • 由於BaseExecutor是BatchExecutor、ReuseExecutor、SimpleExecutor的父類。在執行查詢(query)時,mybatis都會判斷localCache是否存在緩存,如果存在就返回緩存中的值。言外之意就是一級緩存是默認開啟的。

    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : 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 = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
    }

  • CachingExecutor 實現了二級緩存,interceptorChain在這里實現了Executor級別的攔截,返回了一個被代理得執行器對象。CachingExecutor持有了一個BaseExecutor的委托對象,這里就是委托模式得運用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM