注: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上下载。