这可能是把MyBatis缓存特性讲的最清楚的一篇文章了

Mybatis的缓存机制 Mybatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制,缓存可以极大的提升查询效率。 MyBatis中默认定义了两级缓存,分别是一级缓存和二级缓存。 (1) 默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。 (2)二级缓存需要手动开启和配置,二级缓存是基于Mapper(namespace)级别的缓存。 (3)为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存... 阅读详情

最新互联网大厂面试真题、Java程序员面试策略(面试前的准备、面试中的技巧)请移步GitHub


一、缓存简介

一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。

但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”引入了很多问题,比如缓存同步、缓存失效、缓存雪崩等等。当然这些问题不是本文讨论的重点。

本文主要讨论MyBatis缓存这个比较鸡肋的功能。虽然说MyBatis的缓存功能比较鸡肋,但是为了全面了解MyBatis这个框架,学习下缓存这个功能还是挺有必要的。MyBatis的缓存分为一级缓存和二级缓存,下面就分别来介绍下这两个特性。

二、一级缓存

在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。

1. 什么是MyBatis一级缓存

一级缓存是 SqlSession级别 的缓存。在操作数据库时需要构造 sqlSession 对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的 sqlSession 之间的缓存数据区域(HashMap)是互相不影响的。

在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis 提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。

2. 怎么开启一级缓存

MyBatis中一级缓存默认是开启的,不需要我们做额外的操作。

如果你需要关闭一级缓存的话,可以在Mapper映射文件中将flushCache属性设置为true,这种做法只会针对单个SQL操作生效

<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap" flushCache="true">
    select 
    <include refid="Base_Column_List" />
    from cbondissuer
    where OBJECT_ID = #{objectId,jdbcType=VARCHAR}
  </select>

还有一种做法是在MyBatis的主配置文件中,关闭所有的一级缓存

  默认是SESSION,也就是开启一级缓存
  <setting name="localCacheScope" value="STATEMENT"/>

下面我们来写代码验证下MyBatis的一级缓存。

String id = "123";
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
//同一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper10 = sqlSession1.getMapper(CbondissuerMapper.class);
CbondissuerMapper cbondissuerMapper11 = sqlSession1.getMapper(CbondissuerMapper.class);
//另外一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper20 = sqlSession2.getMapper(CbondissuerMapper.class);

//同一个Mapper,同样的SQL查了两次
Cbondissuer cbondissuer10 = cbondissuerMapper10.selectByPrimaryKey(id);
Cbondissuer cbondissuer101 = cbondissuerMapper10.selectByPrimaryKey(id);
//同一个sqlSession创建的Mapper,又查询了一次同样的SQL
Cbondissuer cbondissuer11 = cbondissuerMapper11.selectByPrimaryKey(id);
//不一样的sqlSession创建的Mapper查询了一次同样的SQL
Cbondissuer cbondissuer20 = cbondissuerMapper20.selectByPrimaryKey(id);

System.out.println("cbondissuer10 equals cbondissuer101 :"+(cbondissuer10==cbondissuer101));
System.out.println("cbondissuer10 equals cbondissuer11 :"+(cbondissuer10==cbondissuer11));
System.out.println("cbondissuer10 equals cbondissuer21 :"+(cbondissuer10==cbondissuer20));

sqlSession1.close();
sqlSession2.close();
System.out.println("end...");

上面进行了四次查询,如果你观察日志的话。会发现只进行了两个数据库查询。因为第二和第三次的查询都查询了一级缓存,查出的其实是缓存中的结果。所以输出的结果是

cbondissuer10 equals cbondissuer101 :true
cbondissuer10 equals cbondissuer11 :true
cbondissuer10 equals cbondissuer21 :false

3. 哪些因素会使一级缓存失效

上面的一级缓存初探让我们感受到了 MyBatis 中一级缓存的存在,那么现在你或许就会有疑问了,那么什么时候缓存失效呢?

  • 通过同一个SqlSession执行更新操作时,这个更新操作不仅仅指代update操作,还指插入和删除操作;
  • 事务提交时会删除一级缓存;
  • 事务回滚时也会删除一级缓存;

4. 一级缓存源码解析

其实MyBatis一级缓存的实质就是一个Executor的一个类似Map的属性,分析源码的方法就是看在哪些地方从这个Map中查询了缓存,又是在哪些清空了这些缓存。

①. 查询时使用缓存分析

public abstract class BaseExecutor implements Executor {

  private static final Log log = LogFactory.getLog(BaseExecutor.class);

  protected Transaction transaction;
  protected Executor wrapper;

  protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
  //这个localCache变量就是一级缓存变量
  protected PerpetualCache localCache;
  protected PerpetualCache localOutputParameterCache;
  protected Configuration configuration;
  //..省略下面代码
}

全局搜索代码中哪些地方使用了这个变量,很容易找到BaseExecutor.query方法使用了这个缓存:

public abstract class BaseExecutor implements Executor {

// 省略其他代码
 public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    if (queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }
    List<E> list;
    try {
      queryStack++;
      //先从缓存中查询结果,如果缓存中已经存在结果直接使用缓存的结果
      list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
      if (list != null) {
        handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
      } else {
        //缓存中没有结果从数据库查询
        list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
      }
    } finally {
      queryStack--;
    }
    if (queryStack == 0) {
      for (DeferredLoad deferredLoad : deferredLoads) {
        deferredLoad.load();
      }
      // issue #601
      deferredLoads.clear();
      if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
        // issue #482
        clearLocalCache();
      }
    }
    return list;
  }
  //..省略下面代码
}

上面的代码展示了,BaseExecutor的query方法使用缓存的过程。需要注意的是查询缓存时是根据cacheKey进行查询的,我们可以将这个key简单的
理解为sql语句,不同的sql语句能查出不同的缓存。(注意sql语句中的参数不同也会被认为是不同的sql语句)。

②. 导致一级缓存失效的代码分析

查看BaseExecutor的代码,我们很容易发现是下面的方法清空了一级缓存。(不要问我是怎么发现这个代码的,看代码能力需要自己慢慢提升)

@Override
public void clearLocalCache() {
    if (!closed) {
        localCache.clear();
        localOutputParameterCache.clear();
    }
}

那么我们只要查看哪些地方调用了这个方法就知道哪些情况下会导致一级缓存失效了。跟踪下来,最后发现下面三处地方会使得一级缓存失效

BaseExecutor的update方法,使用MyBatis的接口进行增、删、改操作都会调用到这个方法,这个也印证了上面的说法。

@Override
  public int update(MappedStatement ms, Object parameter) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    clearLocalCache();
    return doUpdate(ms, parameter);
  }

BaseExecutor的commit方法,事务提交会导致一级缓存失败。如果我们使用Spring的话,一般事务都是自动提交的,所以好像MyBatis的一级缓存一直没怎么被考虑过

@Override
  public void commit(boolean required) throws SQLException {
    if (closed) {
      throw new ExecutorException("Cannot commit, transaction is already closed");
    }
    clearLocalCache();
    flushStatements();
    if (required) {
      transaction.commit();
    }
  }

BaseExecutor的rollback方法,事务回滚也会导致一级缓存失效。

@Override
  public void rollback(boolean required) throws SQLException {
    if (!closed) {
      try {
        clearLocalCache();
        flushStatements(true);
      } finally {
        if (required) {
          transaction.rollback();
        }
      }
    }
  }

5. 一级缓存使用建议

平时使用MyBatis时都是和Spring结合使用的,在整个Spring容器中一般只有一个SqlSession实现类。而Spring一般都是主动提交事务的,所以说一级缓存经常失效。

还有就是我们也很少在一个事务范围内执行同一个SQL两遍,上面的这些原因导致我们在开发过程中很少注意到MyBatis一级缓存的存在。

不怎么用并不是说不用,作为一个合格的开发者需要对这些心知肚明,要清楚的知道MyBatis一级缓存的工作流程。

三、二级缓存

1. 什么是MyBatis二级缓存

MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存,开启二级缓存后,会使用 CachingExecutor 装饰 Executor,
进入一级缓存的查询流程前,先在CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示:

当二级缓存开启后,同一个命名空间(namespace) 所有的操作语句,都影响着一个 共同的 cache(一个Mapper映射文件对应一个Cache),也就是二级缓存被多个 SqlSession 共享,是一个全局的变量。当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

从上面的图可以看出,MyBatis的二级缓存实现可以有很多种,可以是MemCache、Ehcache等。也可以是Redis等,但是需要额外的Jar包。

2. 怎么开启二级缓存

二级缓存默认是不开启的,需要手动开启二级缓存,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。开启二级缓存的条件也是比较简单,

step1:通过直接在 MyBatis 配置文件中通过

<settings>  
	<setting name = "cacheEnabled" value = "true" />
</settings>

step2: 在 Mapper 的xml 配置文件中加入 标签

cache标签下面有下面几种可选项

  • eviction: 缓存回收策略,支持的策略有下面几种
    • LRU - 最近最少回收,移除最长时间不被使用的对象(默认是这个策略)
    • FIFO - 先进先出,按照缓存进入的顺序来移除它们
    • SOFT - 软引用,移除基于垃圾回收器状态和软引用规则的对象
    • WEAK - 弱引用,更积极的移除基于垃圾收集器和弱引用规则的对象
  • flushinterval:缓存刷新间隔,缓存多长时间刷新一次,默认不清空,设置一个毫秒值;
  • readOnly: 是否只读;true 只读 ,MyBatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。MyBatis 为了加快获取数据,直接就会将数据在缓存中的引用交给用户。不安全,速度快。读写(默认):MyBatis 觉得数据可能会被修改
  • size : 缓存存放多少个元素
  • type: 指定自定义缓存的全类名(实现Cache 接口即可)
  • blocking:若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。

3. 哪些因素会使二级缓存失效

从上面的介绍可以知道MyBatis的二级缓存主要是为了SqlSession之间共享缓存设计的。但是我们平时开发过程中都是结合Spring来进行MyBatis的开发。在Spring环境下一般也只有一个SqlSession实例,所以二级缓存使用到的机会不多。所以下面就简单描述下Mybatis的二级缓存。

还是以上面的列子为列

String id = "{0003CCCA-AEA9-4A1E-A3CC-06D884BA3906}";
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
//同一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper10 = sqlSession1.getMapper(CbondissuerMapper.class);
CbondissuerMapper cbondissuerMapper11 = sqlSession1.getMapper(CbondissuerMapper.class);
//另外一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper20 = sqlSession2.getMapper(CbondissuerMapper.class);

//同一个Mapper,同样的SQL查了两次
Cbondissuer cbondissuer10 = cbondissuerMapper10.selectByPrimaryKey(id);
Cbondissuer cbondissuer101 = cbondissuerMapper10.selectByPrimaryKey(id);
//同一个sqlSession创建的Mapper,又查询了一次同样的SQL
Cbondissuer cbondissuer11 = cbondissuerMapper11.selectByPrimaryKey(id);
//这边需要提交事务才能让二级缓存生效
sqlSession1.commit();
//不一样的sqlSession创建的Mapper查询了一次同样的SQL
Cbondissuer cbondissuer20 = cbondissuerMapper20.selectByPrimaryKey(id);

System.out.println("cbondissuer10 equals cbondissuer101 :"+(cbondissuer10==cbondissuer101));
System.out.println("cbondissuer10 equals cbondissuer11 :"+(cbondissuer10==cbondissuer11));
System.out.println("cbondissuer10 equals cbondissuer21 :"+(cbondissuer10==cbondissuer20));
  • 二级缓存是以namespace(Mapper)为单位的,不同namespace下的操作互不影响。
  • insert,update,delete操作会清空所在namespace下的全部缓存。
  • 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。

4. 二级缓存使用建议

个人觉得MyBatis的二级缓存实用性不是很大。一个原因就是Spring环境下,一本只有一个SqlSession,不存在sqlSession之间共享缓存;还有就是
MyBatis的缓存都不能做到分布式,所以对于MyBatis的二级缓存以了解为主。

四、简单总结

1. 一级缓存

  • 一级缓存的本质是Executor的一个类似Map的属性;
  • 一级缓存默认开启,将flushCache设置成true或者将全局配置localCacheScope设置成Statement可以关闭一级缓存;
  • 在一级缓存开启的情况下,查询操作会先查询一级缓存,再查询数据库;
  • 增删改操作和事务提交回滚操作会导致一级缓存失效;
  • 由于Spring中事务是自动提交的,因此Spring下的MyBatis一级缓存经常失效。(但是并不表示不生效,除非你手动关闭一级缓存)
  • 不能实现分布式。

2. 二级缓存

  • namesapce级别的缓存(Mapper级别或者叫做表级别的缓存),设计的主要目的是实现sqlSession之间的缓存共享;
  • 开启二级缓存后,查询的逻辑是二级缓存->一级缓存->数据库;
  • insert,update,delete操作会清空所在namespace下的全部缓存;
  • 多表查询一定不要使用二级缓存,因为多表操作进行更新操作,可能会产生脏数据。

总体来说,MyBatis的缓存功能比较鸡肋。想要使用缓存的话还是建议使用spring-cache等框架。

大神带你玩转高级Mybatis——一篇文章精通mybatis—如何使用一级缓存、二级缓存 请关注订阅,本专栏会详细讲解Mybatis,实现网站的开发 本篇内容专门为从事Java后端开发的面试者提供帮助,精准解决面试遇到的问题,欢迎讨论 关注微信公众号,可免费获取资料 什么是缓存? 程序经常要调用的对象存在内存中,方便其使用时可以快速调用,不必去数据库或者其他持久化设备中查询,主要就是提高性能. 一级缓存和二级缓存调用顺序? 优先查询二级缓存-》查询一级缓存-》数据库 Mybatis一级缓存 简介:一级缓存的作用域是SQLSession,同一个SqlSession中执行相同的SQL查询(相同的 阅读详情

相关推荐

【项目立项管理、项目整合管理】30天通过软考高项-第二天

①项目或阶段的概述;②范围目标、范围的评估标准,证明达到完⼯标准的证据;③质量目标、项目和产品质量的评估标准、相关核实信息和实际里程碑交付日期以及偏差原因;④成本目标,包括可接受的成本区间、实际成本,产⽣任何偏差的原因等;⑤最终产品、服务或成果的确认信息的总结;⑥进度计划目标,包括成果是否实现项目预期效益:如果在项目结束时未能实现效益,则指出效益实现程度并预计未来实现情况;

weixin_42520723的博客 1000

MyBatis 一级缓存在分布式下的坑

MyBatis 的一级缓存在单机环境下可以减少与 MySql 的交互,提高性能,但是在分布式环境下容易产生脏数据。建议在生产环境下关闭,使用 Redis,Memcache 等代替。...

GitChat 2990

Gemini国内合规接入指南:API身份链构建与镜像站选型

生成式AI服务接入本质是服务可用性工程,而非单纯网络连通问题。理解大模型API调用原理,关键在于掌握身份认证、权限控制与数据流向三大技术要素。Gemini作为主流多模态模型,其国内可用路径已从‘模拟访问’转向‘能力映射’——聚焦文本生成等核心能力的稳定调用。通过构建七步Google Cloud身份链(含+86实名、国际信用卡核验、Service Account最小权限配置),可实现99.2%高成功率的合规API接入;而教育型、企业型、开发者型三类镜像站则提供差异化过渡方案,均需满足端到端加密、境内CDN托管

weixin_29046035的博客 436

mybatis数据分布式缓存

将缓存数据数据进行分布式管理。

ly10228的博客 349

AR Tag 与 ROS:从基础部署到机器人视觉定位实战

本文详细介绍了AR Tag技术在ROS环境下的部署与应用,涵盖从基础原理到机器人视觉定位的实战技巧。通过分析AR Tag的特征提取、位姿解算等核心技术,结合ROS工具包`ar_track_alvar`的配置优化,帮助开发者实现高精度的视觉定位系统。文章还分享了深度相机配置、坐标转换及性能优化等实用经验,适用于仓储机器人、物流分拣等场景。

weixin_33146151的博客 181

基于STM32的多传感器融合的设施农业小型搬运机器人避障控制系统设计

针对设施农业场景中狭窄通道、障碍物多样(如农机具、作物植株、水管)的特点,设计一款基于 STM32 的小型搬运机器人避障控制系统。系统通过多传感器融合实现 360° 环境感知,采用模糊 PID 控制算法实现平滑避障,满足温室、大棚等场景的搬运需求。通过在温室环境测试,系统可实现对直径≥5cm 障碍物的有效检测(检测距离误差≤5%),避障转向半径≤30cm,平均功耗≤15W。后续可通过增加激光雷达(如 TFmini)提升远距离障碍物检测能力,结合 SLAM 算法实现路径规划。

weixin_42300449的博客 860

Mybatis一级缓存导致分布式环境下的查询脏数据

    Mybatis一级缓存,也称本地缓存,默认是SqlSession级别的缓存。在一次程序与数据库的会话(Sqlsession)中,mybatis会维护一个以hashmap为存储结构的一级缓存,在这个会话中,只要在两次相同条件的查询中间,这个会话里没有出现增删改的操作,那么Mybatis会在第二次查询时候在缓存中将这个结果返回,导致两次查询的返回结果对象其实是一个,用“==”比较结果为true...

qq_19439605的博客 9717

在Simulink中实现基于深度强化学习的控制算法仿真建模

通过上述步骤,你可以在Simulink中实现基于深度强化学习的控制算法仿真建模。这种方法适用于许多复杂的控制问题,尤其是当传统控制方法难以找到有效解决方案时。随着经验的积累,你可以进一步探索不同的深度强化学习算法及其变种,以适应更广泛的应用场景。此外,还可以结合其他先进技术(如迁移学习、多智能体协作等),提升模型的表现能力。

amy_mhd的博客 415

mybatis同一个sql执行多次出现重复数据_这可能是把MyBatis缓存特性讲的最清楚的一篇文章了...

最新互联网大厂面试真题、Java程序员面试策略(面试前的准备、面试中的技巧)请移步GitHub一、缓存简介一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”...

weixin_39715187的博客 1842

【全网首发】2026华为OD双机位C卷 机考真题题库含考点说明以及在线OJ (Java)

如果你收到的是双机位C卷考试通知,需要针对性地调整备考策略。自2025年11月19日起,华为OD机试已正式从双机位A卷切换至。复杂度明显提升,需要组合多个算法点。题面相对简单,直接考查编程基本功。考查问题分析、算法选择和优化能力。通常为1-2个核心算法点的应用。

算法大师! 168

使用机器学习算法预测黄金价格

在本文中,我们将使用线性回归、XGBoost和LSTM这三种不同的机器学习算法来预测黄金价格。接下来,我们使用线性回归、XGBoost和LSTM分别建立了模型,并进行了训练和预测。这些机器学习算法可以帮助我们对黄金价格进行预测,但请注意,市场价格受多种因素影响,因此预测结果可能并不完全准确。接下来,我们需要对数据进行一些预处理,以便用于机器学习模型的训练和测试。我们将使用80%的数据作为训练集,20%的数据作为测试集。最后,我们将绘制每个模型的预测结果,并将其与实际价格进行比较,以评估模型的性能。

QromMatlab的博客 1316

事务中mybatis通过id查不到但是通过其他条件可以查到_这可能是把MyBatis缓存特性讲的最清楚的一篇文章了...

推荐阅读:一线大厂为什么面试必问分布式?在一次又一次的失败中,我总结了这份万字的《MySQL性能调优笔记》并发编程详解:十三个工具类,十大设计模式,从理论基础到案例实战一、缓存简介一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提...

weixin_39968410的博客 90

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

mybatis二级缓存架构原理

一级缓存 与springboot集成时一级缓存不生效原因以及解决方案 如何解决这个问题? 要知道如何解决这个问题, 二级缓存 为什么mybatis默认不开启二级缓存? 不推荐使用。 ...

修理男爵的博客 3857

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

MyBatis 一级缓存与二级缓存

MyBatis 提供两级缓存机制提升查询性能:一级缓存:SqlSession 级别,默认开启二级缓存:Mapper 级别,需手动开启 两者协同工作,形成查询数据优先级:二级缓存 → 一级缓存 → 数据库作用域:单个 SqlSession(数据库会话)生命周期:随 SqlSession 创建而创建随 SqlSession 关闭或清空()而销毁存储位置:内存中的 HashMap(非序列化)默认状态:开启状态,无需配置 2. 工作流程 三、二级缓存(Second Level Cache) 1. 核心特性

qq_62112907的博客 3197

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

MyBatis缓存和二级缓存整合Redis

第⼀次发起查询⽤户username为zjq的⽤户信息,先去找缓存中是否有username为zjq的⽤户信息,如果没有,从 数据库查询⽤户信息。得到⽤户信息,将⽤户信息存储到⼀级缓存中。如果中间sqlSession去执⾏commit操作(执⾏插⼊、更新、删除),则会清空SqlSession中的一级缓存,这样做的⽬的为了让缓存中存储的是最新的信息,避免脏读。第⼆次发起查询⽤户username为zjq的⽤户信息,先去找缓存中是否有username为zjq的⽤户信息,缓存中有,直接从缓存中获取⽤户信息。

write less , do more 7664

MyBatis缓存机制学习

MyBatis缓存机制解析:本文详细介绍了MyBatis的一级缓存和二级缓存机制。一级缓存默认开启,作用域为SqlSession,基于HashMap存储;二级缓存需手动配置,作用域为Mapper级别,支持第三方缓存框架如EhCache。文章通过代码示例演示了缓存特性,测试了缓存生效条件,并详细解析了缓存标签属性(回收策略、刷新间隔等)。同时介绍了MyBatis与EhCache的整合步骤,包括依赖配置、参数调整等。最后分析了二级缓存的适用场景(读多写少、非敏感数据)和局限性(分布式环境不一致、缓存粒度粗等问题

ywl470812087的博客 12万+

Springboot整合Redis作为Mybatis的二级缓存

文章转载声明:转载请附带原文链接 0. 环境准备 以下是我本机的环境: SpringBoot2.3.x Mybatis3.x Redis5.x 本机或者服务器中搭建好redis环境,并启动成功!这里我用的是阿里云学生机上部署的redis5.x IDEA2020.x ,Eclipse2020也是可以的,编辑器选择无所谓! 1. 新版本springboot和IDEA编辑器踩坑(可以直接跳过该章节,遇到类似的错误再回头看) 如果您在实操过程中,使用的是IDEA2020 和springboot2.3.x 版.

兴趣使然的草帽路飞 1万+

MyBatis-Plus一级缓存和二级缓存-redis解决缓存的脏数据

一级缓存:也称为本地缓存,基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为SqlSession,用于保存用户在一次会话过程中查询的结果,用户一次会话中只能使用一个sqlSession,各个SqlSession之间的缓存相互隔离,当 Session flush 或 close 之后,该 SqlSession 中的所有 Cache 就将清空,MyBatis默认打开一级缓存、不允许关闭。MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。

tiger_Angle 4840

mybatis之一级缓存和二级缓存~

根据二级缓存的工作机制一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中`,**如果当前会话关闭了,这个会话对应的一级缓存就没有了,但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中,新的会话查询信息,就可以从二级缓存中获取内容** 而我们上述写法会话1和会话2同时打开同时关闭的做法显然不符合二级缓存工作机制。

m0_64365419的博客 3559

MyBatis——关于一级缓存 & 二级缓存的案例详解

MyBatis——关于一级缓存 & 二级缓存的案例详解

贝尔摩德苦艾酒 8127

【Mybatis学习】学习 Mybatis 一篇文章就够了(珍藏版)

文章目录一、学习目录二、扩展目录 一、学习目录 二、扩展目录

南淮北安的博客 1043

MyBatis的cache缓存

缓存是计算机中的一块存储区域,把数据放入到存储区域中,读取速度快每当我们使用MyBatis开启一次和数据库的会话,MyBatis会创建出一个SqlSession对象表示一次数据库会话。在对数据库的一次会话中,我们有可能会反复地执行完全相同的查询语句,如果不采取一些措施的话,每一次查询都会查询一次数据库,而我们在极短的时间内做了完全相同的查询,那么它们的结果极有可能完全相同,由于查询一次数据库的代价很大,这有可能造成很大的资源浪费。...

weixin_73468155的博客 1757

Mybatis知识点详细总结:一篇文章带你全面掌握

MyBatis是一个简化数据库操作的持久层框架,它封装了JDBC,使开发者能够更简洁地执行SQL语句。

weixin_53818428的博客 634

MyBatis缓存原理

提示:自从上次发现mybatis缓存可被修改后,就一直想针对myBatis缓存单独做一期分析,包含其原理和运行方式,现在终于得空来详细写一篇了熟悉MyBatis的应该知道,MyBatis内置了两级缓存,会在查询数据库时,将查询结果缓存到内存中,以便下次查询时可以直接从缓存中获取数据,从而提高数据查询效率MyBatis缓存一般分为一级缓存和二级缓存。一级缓存是指MyBatis自身的缓存机制,是SqlSession级别的缓存。

战斧的博客 7539
上一篇: 程序员职场小技巧:每天工作那么多事,如何安排事务的优先级?
下一篇: 如何设计一个基础服务?看完这篇文章别再说不会、不懂、不知道
Java_Cappuccino
博客等级 码龄7年 17粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值