MyBatis中的緩存機制

MyBatis中的緩存機制

通常的ORM(Object Relational Mapping)框架都會提供緩存功能以減小訪問數據庫的次數,減輕數據庫壓力,提升查詢效率。MyBatis中有一級和默認實現的二級緩存,並且MyBatis也預留了集成第三方緩存的接口(二級緩存接口的自定義實現)。sql

先經過一段源碼來看看mybatis的查詢的執行流程。數據庫

1> openSqlSession()->getMapper()->query(),mybatis中最終的執行是交給Executor執行器來執行的,Executor接口的實現類中有一個CachingExecutor類(這是mybatis實現的二級緩存)。緩存

2> 執行query方法mybatis

 1 @Override
 2 public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
 3     throws SQLException {
 4   //獲取緩存對象
 5   Cache cache = ms.getCache();
 6   if (cache != null) {//存在緩存
 7     //嘗試刷新緩存,確保緩存是最新
 8     flushCacheIfRequired(ms);
 9     //若是緩存啓用而且該查詢沒有用到ResultHandler
10     if (ms.isUseCache() && resultHandler == null) {
11       //參數檢查
12       ensureNoOutParams(ms, boundSql);
13       @SuppressWarnings("unchecked")
14       //從緩存中讀取
15       List<E> list = (List<E>) tcm.getObject(cache, key);
16       if (list == null) {//未命中,調用默認執行器執行query
17         list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
18         //查詢結果放入緩存
19         tcm.putObject(cache, key, list); // issue #578 and #116
20       }
21       return list;
22     }
23   }
24   return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
25 }

 

經過上面一段代碼,能夠發現如下兩個問題:app

  • 首先,你們大概能夠猜想出mybatis中一級緩存和二級緩存的優先級順序了吧?😂沒錯,在開啓二級緩存的狀況下會先從二級緩存中讀取——>二級緩存未命中的話會調用默認執行器的query方法——>默認執行器再讀取本身的一級緩存——>未命中則訪問數據庫——>查詢結果放入緩存。框架

  • 二級緩存是保存在MappedStatement中的,MappedStatement是用來存放咱們的定義DAO層的mapper的信息。一個mapper接口對應一個MappedStatement,那麼二級緩存的做用域就是同一mapper下有效。ide


一級緩存:

mybatis 的一級緩存是sqlSession級別的,緩存做用域是在一次數據庫會話中有效。一級緩存是持久化緩存(本地緩存)而且是默認開啓的,不須要手動開啓。ui

爲何說一級緩存是Session級別的而且是本地緩存呢?mybatis中每個sqlSession都會對應一個繼承自BaseExecutor的Executor(默認是SimipleExecutor)。而BaseExecutor中存在兩個PerpetualCache類型的實現Cache接口的對象,見名知意,它就是一個持久化的緩存對象,具體的持久化實現很少贅述(沒看😢)。spa

  

爲了不髒讀,sqlSession執行了DML操做(insert、update、delete),並commit了以後,mybatis會清空當前sqlSession緩存中的全部緩存數據。code


二級緩存

從開頭的源碼解讀能夠看出,二級緩存的做用域是同一mpper接口,全部的sqlSession查詢結果都會走MapperStatement中的Cache。mybatis中的二級緩存默認是關閉的須要手動開啓。

開啓mybatis二級緩存的方法:

  • 在mybatis配置文件中添加下面的設置

    <settings>
            <setting name="cacheEnabled" value="true"/>
    </settings>
  • 在須要開啓二級緩存的mapper.xml文件中添加下面的配置

    <!-- 當前mapper下全部語句開啓二級緩存 -->
    <!-- 也能夠在對應的mapper接口上添加@CacheNamespace註解 -->
    <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>

    具體的執行流程能夠看開頭的源碼解析,不過多贅述

相關文章
相關標籤/搜索