1. 程式人生 > >通過源碼分析MyBatis的緩存

通過源碼分析MyBatis的緩存

true hex int 代碼 ase 是個 .com style bool

  看了通過源碼分析MyBatis的緩存這篇文章後,自己跟著源碼過了一遍,對mybatis的一級緩存和二級緩存有了更清楚的認識。

  一級緩存是SqlSession級別的,同一個sqlSession在第二次執行一個相同參數的select語句並且第一次執行後沒有對數據進行更新,就會直接從緩存取值,而不再進行查找。通過閱讀源碼了解了這個過程,首先org.apache.ibatis.session.defaults.DefaultSqlSession.select(String, Object, RowBounds, ResultHandler)方法會調用executor.query(ms, wrapCollection(parameter), rowBounds, handler),然後分析executor的類型,在org.apache.ibatis.session.defaults.DefaultSqlSessionFactory類中,openSessionFromDataSource(ExecutorType, TransactionIsolationLevel, boolean)方法的Executor executor = configuration.newExecutor(tx, execType) 語句實例化executor,代碼如下,在SqlMapConfig.xml中cacheEnabled默認為true,即一級緩存默認開啟,故executor為CachingExecutor類型。

/*     */   public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
/* 540 */     executorType = executorType == null ? defaultExecutorType : executorType;
/* 541 */     executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
/*     */     Executor executor;
/* 543 
*/ if (ExecutorType.BATCH == executorType) { /* 544 */ executor = new BatchExecutor(this, transaction); } else { Executor executor; /* 545 */ if (ExecutorType.REUSE == executorType) { /* 546 */ executor = new ReuseExecutor(this, transaction); /* */ } else /* 548 */ executor = new
SimpleExecutor(this, transaction); /* */ } /* 550 */ if (cacheEnabled) { /* 551 */ executor = new CachingExecutor(executor); /* */ } /* 553 */ Executor executor = (Executor)interceptorChain.pluginAll(executor); /* 554 */ return executor; /* */ } /* */

  在org.apache.ibatis.executor.CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler, CacheKey, BoundSql)方法中首先獲取二級緩存,由於二級緩存為空,執行該語句

return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);

  delegate對象為org.apache.ibatis.executor.SimpleExecutor類型,繼承自org.apache.ibatis.executor.BaseExecutor類,query方法如下

技術分享圖片

BaseExecutor的屬性localCache是個PerpetualCache類型的實例,PerpetualCache類是實現了MyBatis的Cache緩存接口的實現類之一,內部有個Map<object, object>類型的屬性用來存儲緩存數據。 這個localCache的類型在BaseExecutor內部是寫死的。 這個localCache就是一級緩存!

技術分享圖片

在數據更改時會清空緩存。

二級緩存是基於namespace的,必須在sqlSession提交或關閉才會生效。需要在mapper配置文件加上<cache />。

通過源碼分析MyBatis的緩存