注:Mybatis的版本是3.5.0。java
先上一張圖數據庫
圖1 Mybatis查詢時使用LocalCacheapache
LocalCache,也被稱爲一級緩存,有以下特色:緩存
LocalCacheScope有倆個值,以下List-1所示session
List-1 LocalCacheScope的值有枚舉值fetch
package org.apache.ibatis.session; /** * @author Eduardo Macarron */ public enum LocalCacheScope { SESSION, STATEMENT }
Configuration中localCacheScope默認值是SESSION,以下List-2所示this
List-2 Configuration的屬性localCacheScope默認值是SESSIONspa
package org.apache.ibatis.session; ..... /** * @author Clinton Begin */ public class Configuration { ...... protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION; ......
爲何說LocalCache生命週期與SqlSession一致,如List-3所示:code
List-3 DefaultSqlSessionFactory的openSessionFromDataSource和openSessionFromConnection對象
package org.apache.ibatis.session.defaults; ...... /** * @author Clinton Begin */ public class DefaultSqlSessionFactory implements SqlSessionFactory { ...... private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) { try { boolean autoCommit; try { autoCommit = connection.getAutoCommit(); } catch (SQLException e) { // Failover to true, as most poor drivers // or databases won't support transactions autoCommit = true; } final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); final Transaction tx = transactionFactory.newTransaction(connection); final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } ......
List-3中的方法openSessionFromDataSource和方法openSessionFromConnection中的configuration.newExecutor(tx, execType)的實現以下List-4所示。每次實例化一個DefaultSqlSession時,都會實例化一個SimpleExecutor,而用於一級緩存的localCache就在BaseExecutor中,BaseExecutor是SimpleExecutor的父類。因此當SqlSession對象被銷燬時,它的Executor也被銷燬,因此localCache也被銷燬。
List-4 newExecutor中默認狀況下新建SimpleExecutor
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; }
1.https://www.jianshu.com/p/c553169c5921,這篇博客寫的挺好的。
2.Mybatis源碼,去Github上下載。