Mybatis之一级缓存(localCache缓存)简析

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

注:Mybatis的版本是3.5.0。

1.LocalCache(一级缓存)

    先上一张图

               Mybatis之一级缓存(localCache缓存)简析_第1张图片

                                                      图1 Mybatis查询时使用LocalCache

    LocalCache,也被称为一级缓存,有如下特点:

  •     它的生命周期与SqlSession一致。
  •     底层用HashMap实现,没有缓存内容更新和过期。
  •     有个多个SqlSession时,且有数据库写,会出现脏读的情况,一级缓存慎用,或者将Scope设置为Statement。

    LocalCacheScope有俩个值,如下List-1所示

    List-1 LocalCacheScope的值有枚举值

package org.apache.ibatis.session;

/**
 * @author Eduardo Macarron
 */
public enum LocalCacheScope {
    SESSION, STATEMENT
}

    Configuration中localCacheScope默认值是SESSION,如下List-2所示

    List-2 Configuration的属性localCacheScope默认值是SESSION

package org.apache.ibatis.session;
.....

/**
 * @author Clinton Begin
 */
public class Configuration {
  ......
  protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
  ......

    

    为什么说LocalCache生命周期与SqlSession一致,如List-3所示:

    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;
}

   

2.参考

    1.https://www.jianshu.com/p/c553169c5921,这篇博客写的挺好的。

    2.Mybatis源码,去Github上下载。

转载于:https://my.oschina.net/u/2518341/blog/1829868

你可能感兴趣的:(Mybatis之一级缓存(localCache缓存)简析)