前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis之一级缓存(localCache缓存)简析

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

作者头像
克虏伯
发布2019-04-15 11:11:39
4.2K0
发布2019-04-15 11:11:39
举报

注:Mybatis的版本是3.5.0。

1.LocalCache(一级缓存)

    先上一张图

                                                      图1 Mybatis查询时使用LocalCache

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

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

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

List-1 LocalCacheScope的值有枚举值

代码语言:javascript
复制
package org.apache.ibatis.session;

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

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

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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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上下载。

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018/06/13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.LocalCache(一级缓存)
  • 2.参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档