Mybatis 源码学习(七) 缓存的刷新

Mybatis二级缓存详解 基于3.5.10版本的Mybatis源码,彻底搞清楚二级缓存是什么,是在哪里生效的,是怎么开启的,各自作用域是什么 阅读详情

之前学习了mybatis的一级缓存和二级缓存。

那么当数据库数据有跟新的时候,缓存是如何被刷新的呢?

找到update的实现源码:

  public int update(String statement, Object parameter) {
    try {
      dirty = true;
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.update(ms, wrapCollection(parameter));
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

看来是在executor中清理的。

public class CachingExecutor implements Executor {
  
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
    flushCacheIfRequired(ms); //这里清空了二级缓存
    return delegate.update(ms, parameterObject);
  }
 
 private void flushCacheIfRequired(MappedStatement ms) {
    Cache cache = ms.getCache();
    if (cache != null && ms.isFlushCacheRequired()) {
      dirty = true; // issue #524. Disable using cached data for this session
      tcm.clear(cache);
    }
  }
}

public abstract class BaseExecutor implements Executor {
  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);
  }
}
  public void clearLocalCache() {
    if (!closed) {
      localCache.clear();
      localOutputParameterCache.clear();
    }
  }

一级缓存比较简单清晰,同一个sqlSession执行查询的时候缓存,再执行相同查的时候使用缓存,当执行修改操作的时候,直接刷新整个sqlSession的缓存(在Executer上的localCache)。



二级缓存的更新一直让我有点困惑,缓存是在MappedStatement上的,怎么能在修改的时候把其他的查询缓存清除呢,他们是在不同的MappedStatement上的啊?

先看查询的时候是怎么放到缓存的

  @Override
  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
      throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
      flushCacheIfRequired(ms);
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, parameterObject, boundSql);
        @SuppressWarnings("unchecked")
        List<E> list = (List<E>) tcm.getObject(cache, key);
        if (list == null) {
          list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
          tcm.putObject(cache, key, list); // issue #578 and #116
        }
        return list;
      }
    }
    return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

  public void putObject(Cache cache, CacheKey key, Object value) {
    getTransactionalCache(cache).putObject(key, value);
  }
  private TransactionalCache getTransactionalCache(Cache cache) {
    TransactionalCache txCache = transactionalCaches.get(cache);
    if (txCache == null) {
      txCache = new TransactionalCache(cache);
      transactionalCaches.put(cache, txCache);
    }
    return txCache;
  }

从以上的三个方法可以看到,是通过TransactionalCacheManager来放入缓存的。在放入mappedStatement的缓存同时,还被存入了executror下的tcm属性的transactionalCaches对象内容。这是有点绕。如下图所看到的,通过层层代理,最终看到id是mapper的名字。这样其他的SqlSession在查询的时候先查缓存中是否已经存在。刷新的时候也是按照mapper来刷新的。大功告成!


MyBatis源码剖析 在二级缓存的设计上,MyBatis大量的运用了装饰者模式,如CacheExecutor,以及各种Cache接口的装饰器。二级缓存实现了sqlSession之间的缓存数据共享,属于namespace级别;二级缓存具有丰富的缓存策略;二级缓存可由多个装饰器与基础缓存组合而成;二级缓存工作由一个缓存装饰器CacheExecutor和一个事务型预缓存TransactionalCache完成。问题:在开发过程中很多时候我们并不总是需要在获取用户信息的时候加载订单信息,此时就是我们所说的延迟加载。 阅读详情

相关推荐

Android手机免root玩转Kali NetHunter:Termux保姆级安装指南(附Kex VNC配置)

本文提供了一份详细的Android手机免root安装Kali NetHunter的保姆级指南。通过使用Termux终端模拟器,用户无需解锁Bootloader或获取root权限,即可在普通安卓设备上部署完整的Kali Linux渗透测试环境。教程涵盖了从环境准备、NetHunter核心安装到配置Kex VNC实现图形桌面访问的全过程,并附带了电脑投屏与常见问题解决方案,旨在打造一个便携的移动安全学习与测试平台。

weixin_29208327的博客 293

MyBatis——MyBatis数据源与连接池

博文主要介绍MyBatis数据源与连接池,更好的理解MyBatis数据源与连接池。

庄小焱 1731

SAP 配额修改 + 修改记录写入实现

采购配额修改并写入修改记录 cdhdr 和 cdpos

GAVIN 1095

mybatis一级缓存、二级缓存以及缓存被刷新的情况

一级缓存:是session级别的缓存,默认开启,在一个session没有关闭的情况下执行两次相同的查询,第二次查询会从缓存中获取数据。 一级缓存被刷新的情况:在两次相同查询之间插入其他操作(如:增删改),session的缓存会被清空,执行下一次查询会重新执行sql语句。 二级缓存:默认关闭,如果在不同的session范围内,执行相同的数据查询,那么每次查询都是独立地从数据库查询。 二级缓存被刷新的...

每天就学一点点的博客 2720

4.7W防削顶单声道D类音频功率放大器HT6872介绍

HT6872是一款低EMI,防削顶失真,单声道免滤波D类音频功率放大器。在6.5V电源,10%THD+N,4Ω负载条件下,输出4.71W功率,在各类音频终端应用中维持高效率并提供AB类放大器的性能。

weichen_78的博客 4696

告别License烦恼:手把手教你用VS Code+Cppcheck搭建免费的MISRA-C代码检查环境

本文详细介绍了如何使用VS Code和开源工具Cppcheck搭建免费的MISRA-C代码检查环境,帮助开发者规避商业工具的高额License费用。通过四步环境搭建和实战技巧,实现高效的代码静态检查,提升嵌入式开发的安全性和可靠性。

weixin_42523326的博客 247

mybatis数据库连接池介绍和源码剖析

mybatis数据库连接池分析介绍 一、数据库连接池 1、定义 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。 (百度百科) 2、核心原理 连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户

专栏 885

1. 基于STM32的1.28寸圆形IPS屏(GC9A01)驱动移植实战:软件SPI与硬件SPI双方案详解

本文详细介绍了如何在STM32平台上为1.28寸圆形IPS屏(GC9A01驱动芯片)移植驱动程序,涵盖软件SPI与硬件SPI两种实现方案。内容从引脚定义、工程搭建、GPIO配置到SPI外设初始化逐步详解,并提供了完整的测试代码,帮助开发者根据项目需求(灵活性或性能)选择合适的通信方式,快速点亮屏幕并集成到智能手表等嵌入式项目中。

weixin_42300144的博客 203

Mybatis-数据库连接池

数据库连接池是个容器,负责分配、管理数据库连接(Connection)它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏。也就是,如果某个操作占用的连接超出了预定的时间,就会自动释放连接。

weixin_61605998的博客 2285

深入理解 DDR5 Bank Group 与并行调度机制

Bank Group架构和并行调度机制,是DDR5性能跃升的核心秘密!理解它们才能写出高效调度程序,设计出性能强劲又稳定的DDR5系统。🎯记住:Bank Group不是简单的分组,而是高速并行的“魔法钥匙”,巧用它,你的DDR5设计将爆发惊人性能!

weixin_43199439的博客 310

Python和Spyder:一个完美的编程组合

而Spyder作为一个专门为科学计算和数据分析而设计的IDE,提供了高效的开发环境和丰富的工具。无论是初学者还是专业开发者,Python和Spyder都能满足他们的需求,并为他们的工作带来便利和效率。本文将探讨Python和Spyder之间的关系,以及它们如何相互配合,提供一流的编程体验。每个工具都有其特定的优势和适用场景,开发者可以根据自己的需求选择合适的工具。而Spyder作为一个专门为科学计算而设计的IDE,提供了编写、调试和执行Python代码的环境。

CodeHeroicX的博客 1123

MyBatis的缓存

一级缓存是 Sqlsession 级别的 , 需要使用同一个Sqlsession ,经过Sqlsession查询出来的数据,如果下次查询了相同的数据,那么就会在缓存里面查找数据,不需要重新查询。

藜笙的博客 1142

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【MyBatis】MyBatis 二级缓存全详解

上一篇文章中我们介绍到了 MyBatis 一级缓存其实就是 SqlSession 级别的缓存,什么是 SqlSession 级别的缓存呢?一级缓存的本质是什么呢?以及一级缓存失效的原因?我希望你在看下文之前能够回想起来这些内容。,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存,开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示。

九师兄 1万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

mybatis缓存以及数据什么时候更新,实时更新数据(源码详细解释)

用mybatis的基本上都知道mybatis有两个级别的缓存,分别是一级缓存和二级缓存。简单的说: 一级缓存 缓存sql语句返回的数据信息,下次再访问相同的语句时,就会直接从缓存中取数据,就不需要查询数据库了,这样可以减少数据库的访问压力。 二级缓存 待定。 一级缓存的数据更新 我们的疑问: 当我们了解一级缓存的用途后,我们就会想,我们对数据库的操作又不是仅限于读,很多时候我们都要更新数据库的信息...

shenhaiyushitiaoyu的博客 5782

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

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

【MyBatis源码】MyBatis缓存机制源码分析

MyBatis提供了一个配置参数localCacheScope,用于控制一级缓存的级别,该参数的取值为SESSION、STATEMENT,当指定localCacheScope参数值为SESSION时,缓存对整个SqlSession有效,只有执行DML语句(更新语句)时,缓存才会被清除。MyBatis的一级缓存,用户只能控制缓存的级别,并不能关闭。需要注意的是,PerpetualCache类重写了Object类的equals()方法,当两个缓存对象的Id相同时,即认为缓存对象相同。

发现问题,面对问题,分析问题,解决问题,总结问题 903

MyBatis-Plus批量插入操作缓存刷新问题解析

在日常开发中,批量插入(Batch Insert)是提升数据库操作性能的重要手段。然而,很多开发者在MyBatis-Plus中使用批量插入功能时,经常会遇到一些意想不到的问题:**数据不一致、主键冲突、缓存污染**等。这些问题往往源于对MyBatis缓存机制和批量操作执行流程的理解不足。 本文将深入剖析MyBatis-Plus批量插入操作中的缓存刷新问题,通过源码分析、场景复现和解决方案,帮助开...

gitblog_01403的博客 510

mybatis中的缓存(一级缓存、二级缓存)

在计算机的世界中,缓存无处不在,重要性不言而喻。作为一款优秀的ORM框架,MyBatis中又岂能少得了缓存,本博客基于mybatis 3.5.11版本,全面介绍mybatis一级缓存、二级缓存以及自定义缓存的使用方法、实现原理、应用场景、优缺点等,并进行验证,带你彻底掌握MyBatis缓存。

m0_62943934的博客 1万+

mybatis源码学习:一级缓存和二级缓存分析

目录 零、一级缓存和二级缓存的流程 一级缓存总结 二级缓存总结 一、缓存接口Cache及其实现类 二、cache标签解析源码 三、CacheKey缓存项的key 四、二级缓存TransactionCache 五、二级缓存测试 六、一级缓存源码解析 七、测试一级缓存 前文传送门:mybatis源码学习:从SqlSessionFactory到代理对象的生成 零、一级缓存...

weixin_29138993的博客 608

Mybatis二级缓存源码分析

本文中有些内容与之前关于一级缓存分析的文章中,有部分内容相似,所以有些会直接跳过,建议可以先看看关于一级缓存分析的文章一级缓存源码分析 二级缓存生命周期 mybatis一级缓存生命周期是sqlSession级别,二级缓存生命周期是sqlSessionFactory级别,也就是整个应用级别的生命周期。 如何开启二级缓存 mybatis二级缓存与一级缓存不同,需要先在全局配置文件中配置,默认开启 <setting name="cacheEnabled" value="true" /> 还需要在ma

自律使我自由 2709

mybatis 解决join语句缓存刷新研究

项目中由于需要从ibatis升级到mybatis,因为实现的改变,缓存功能也相应的改变,由于需要实现一个当前mybatis没提供的缓存功能,花了些时间研究了源码,并且实现了相应的功能,现就一些心得与大家分享,由于实现中使用了mybatis的plugin拦截器,有可能会改变mybatis的核心行为,所以不保证我的方法足够的安全,只是一个解决问题的思路,言归正传: 在mybatis下每个mapper...

xwycs的专栏 338

Mybatis源码学习:一级缓存和二级缓存分析

文章目录零、一级缓存和二级缓存的流程一级缓存总结二级缓存总结一、缓存接口Cache及其实现类二、cache标签解析源码三、CacheKey缓存项的key四、二级缓存TransactionCache五、二级缓存测试六、一级缓存源码解析七、测试一级缓存 零、一级缓存和二级缓存的流程 以这里的查询语句为例。 一级缓存总结 以下两种情况会直接在一级缓存中查找数据 主配置文件或映射文件没有配置二级...

天乔巴夏丶 684

Mybatis源码解析之二级缓存

前言:     在上一篇文章Mybatis源码解析之一级缓存中分析了Mybatis一级缓存的使用及源码分析。     本篇博客就继续从源码角度来分析关于Mybatis的二级缓存。   1.二级缓存使用     项目配置均同一级缓存的配置相同,不同点就是     1)在blog.xml中假如&lt;cache/&gt;标签 &lt;?xml version="1.0" encodi...

恐龙弟旺仔的博客 809

mybatis源码阅读之6:mybatis缓存

上一篇mybatis底层参数封装过程 下一篇mybatis源码执行流程 mybaits含有一个非常强大的查询缓存功能,可以非常方便的定制。 mybatis默认定义了两级缓存:一级缓存和二级缓存 1.默认情况下,只有一级缓存开启(SqlSession级别的缓存,也成为本地缓存)。 2.二级缓存需要手动开启和配置,他是基于namespace级别的缓存(全局缓存) 3.为了提高扩展...

licwzy的博客 444

MyBatis 二级缓存 关联刷新实现

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天14:00更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细...

weixin_44421461的博客 318

MyBatis源码分析--一级缓存、二级缓存原理

有点项目经验的朋友都知道缓存的重要性是不言而喻的,不仅仅我们在开发项目业务功能的时候使用了各种缓存,框架在设计的时候也有框架层面的缓存,尤其在查询多的场景下,缓存可以大大的减少数据库访问,提升系统效率,Mybatis 也提供了缓存,分别为一级缓存和二级缓存,默认的情况下,Mybatis 只开启一级缓存。

weixin_42118323的博客 1407
上一篇: Mybatis 源码学习(六) Transaction事务模块
下一篇: Mybatis 配置报错:元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?.....
天天
博客等级 码龄21年 219粉丝 146原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值