mybatis的缓存机制

这篇具有很好参考价值的文章主要介绍了mybatis的缓存机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

视频教程_免费高速下载|百度网盘-分享无限制 (baidu.com)

MyBatis 有一套灵活而强大的缓存机制,主要分为两级缓存:一级缓存(本地缓存)和二级缓存(全局缓存)。

  1. 一级缓存(本地缓存)

    • 一级缓存是 MyBatis 默认开启的缓存,它指的是在同一个 SqlSession 中执行相同 SQL 语句时,第一次查询的结果会被缓存起来,后续再执行相同的查询,直接从缓存中获取结果,而不再去查询数据库。

    • 一级缓存是基于 SqlSession 的生命周期的,当 SqlSession 关闭时,一级缓存也就失效了。

    • 一级缓存可以通过清空缓存或提交事务来手动刷新,默认情况下,只要 SqlSession执行一条语句,就会刷新,不会等到 SqlSession结束(不像二级缓存)

    • 一级缓存,在进行DML操作后,会使得缓存失效

    • 一个会话DML操作只会重置当前会话的缓存,不会重置其他会话的缓存,也就是说,其他会话缓存是不会更新的!

  2. 二级缓存(全局缓存)

    • 二级缓存是全局缓存,可以跨多个 SqlSession 共享缓存,但是只有当一个SqlSession结束之后会刷新二级缓存。所以当 SqlSession1和 SqlSession2都没结束且查询同样内容的时候,不会调用二级缓存,因为二级缓存啥都没有。

    • 二级缓存需要在 MyBatis 的配置文件中进行配置启用,并且需要在映射文件中指定哪些语句使用二级缓存。

      不希望某个方法开启缓存呢?我们可以添加useCache属性来关闭缓存:

      <select id="getStudentBySid" resultType="Student" useCache="false">
          select * from student where sid = #{sid}
      </select>
    • 对于同一个 namespace 下的语句,如果开启了二级缓存,它们的查询结果会被缓存在一个全局的缓存区域中,当其他 SqlSession 执行相同的查询时,可以从全局缓存中获取结果。

    • 二级缓存是基于 namespace 级别的,不同的 namespace 有独立的缓存区域,它们之间不会相互影响。

    • 二级缓存默认是开启的,但需要在映射文件中明确指定 <cache/> 元素,才会对该 namespace 启用缓存。

      <mapper namespace="com.example.BlogMapper">
        <cache
          eviction="FIFO"
          flushInterval="60000"
          size="512"
          readOnly="true"/>
        
        <!-- 其他映射语句 -->
      </mapper>
      

      namespace="com.example.BlogMapper":指定缓存的 namespace,即当前映射文件所属的命名空间。这个命名空间用于标识二级缓存的作用范围,是一个唯一的标识符,通常与映射器接口或者类的全路径名相对应。eviction="FIFO":指定缓存的淘汰策略。在这里,FIFO 表示采用先进先出(First In, First Out)策略,即最先进入缓存的数据最先被淘汰。flushInterval="60000":指定缓存刷新的时间间隔,单位为毫秒。在这里,设置为 60000 毫秒,即 60 秒,表示 MyBatis 会定期刷新缓存,清理过期的缓存项。size="512":指定缓存的最大项数。当缓存中的项数达到设定的值时,MyBatis 会尝试清理缓存。readOnly="true":指定是否只读。设置为 true 时,表示缓存只读,不会修改缓存中的数据,可以提高性能。默认值为 falsereadOnly="true":指定是否只读。设置为 true 时,表示缓存只读,不会修改缓存中的数据,可以提高性能。默认值为 false

    • 二级缓存的实现是可插拔的,可以自定义缓存实现,如使用 Ehcache、Redis 等。

    • 添加了二级缓存之后,会先从二级缓存中查找数据,当二级缓存中没有时,才会从一级缓存中获取,当一级缓存中都还没有数据时,才会请求数据库

需要注意的是,缓存机制虽然能提高查询性能,但在一些更新操作(例如插入、更新、删除)时,可能会导致缓存的数据不一致。因此,在执行这类操作时,MyBatis 会自动清空相关的缓存,保证数据的正确性。开发者也可以通过手动清理缓存来控制缓存的行为。

mybatis的缓存机制,mybatis,缓存

虽然缓存机制给我们提供了很大的性能提升,但是缓存存在一个问题,我们之前在计算机组成原理中可能学习过缓存一致性问题,也就是说当多个CPU在操作自己的缓存时,可能会出现各自的缓存内容不同步的问题,而Mybatis也会这样,我们来看看这个例子:

public static void main(String[] args) throws InterruptedException {
    try (SqlSession sqlSession = MybatisUtil.getSession(true)){
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        while (true){
            Thread.sleep(3000);
            System.out.println(testMapper.getStudentBySid(1));
        }
    }
}

我们现在循环地每三秒读取一次,而在这个过程中,我们使用IDEA手动修改数据库中的数据,将1号同学的学号改成100.

结果是依小明的sid并没有发生改变,这也证明了Mybatis的缓存在生效,因为我们是从外部进行修改,Mybatis不知道我们修改了数据,所以依然在使用缓存中的数据,但是这样很明显是不正确的,因此,如果存在多台服务器或者是多个程序都在使用Mybatis操作同一个数据库,并且都开启了缓存,需要解决这个问题,要么就得关闭Mybatis的缓存来保证一致性

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

cacheEnabled 是一个全局开关,用于控制是否开启缓存。在这里,将其值设置为 false,表示禁用缓存。 

<select id="getStudentBySid" resultType="Student" useCache="false" flushCache="true">
    select * from student where sid = #{sid}
</select>
  • useCache="false":这个属性用于指定是否使用缓存。在这里,useCache 被设置为 false,表示禁用缓存。即使全局缓存配置是启用的,这个查询也不会使用缓存。

  • flushCache="true":这个属性用于指定是否刷新缓存。在这里,flushCache 被设置为 true,表示在执行这个查询之前会刷新(清空)缓存。即使全局缓存是启用的,这个查询会强制刷新缓存,确保获取最新的结果。

要么就需要实现缓存共用,也就是让所有的Mybatis都使用同一个缓存进行数据存取,在后面,我们会继续学习Redis、Ehcache、Memcache等缓存框架,通过使用这些工具,就能够很好地解决缓存一致性问题

 文章来源地址https://www.toymoban.com/news/detail-804009.html

到了这里,关于mybatis的缓存机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mybatis学习|Mybatis缓存:一级缓存、二级缓存

    MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存) 二级缓存需要手动开启和配置,他是

    2024年02月09日
    浏览(27)
  • MyBatis的缓存,一级缓存,二级缓存

    10.1、MyBatis的一级缓存 一级缓存是SqlSession级别的,通过 同一个 SqlSession对象 查询的结果数据会被缓存,下次执行 相同的查询语句 ,就 会 从缓存中(缓存在内存里) 直接获取,不会重新访问数据库(数据库在磁盘里),也就是说就执行一次sql。一级缓存 默认开启 。 使一级

    2024年02月07日
    浏览(37)
  • MyBatis第六讲:MyBatis缓存

    MyBatis 提供了一级缓存和二级缓存的支持。默认情况下,MyBatis 只开启一级缓存。 8、1MyBatis一级缓存 一级缓存是基于MyBatis自带的 HashMap 本地缓存,作用范围为 SqlSession 域内。当刷新或者关闭之后,该 SqlSession 中所有的缓存就会被清空。 在参数和 SQL 完全一样的情况下,我们使

    2024年02月11日
    浏览(36)
  • HTTP 缓存机制——强制缓存和协商缓存

    对于一些具有重复性的 HTTP 请求,比如每次请求得到的数据都一样的,我们可以把这对「请求-响应」的数据都缓存在本地,那么下次就直接读取本地的数据,不必在通过网络获取服务器的响应了 HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存。 强缓存指的是只要浏览

    2024年01月25日
    浏览(35)
  • 23-MyBatis缓存、本地缓存、分布式Redis缓存、前端缓存

             MyBatis一级缓存、          MyBatis二级缓存、          本地缓存:单节点          分布式Redis缓存:多节点          前端sessionStorage缓存:会话缓存          前端localStorage缓存:前端本地缓存 MyBatis一级缓存默认是开启的。 在Spring Boot中需要添加

    2024年02月13日
    浏览(29)
  • MyBatis缓存和二级缓存整合Redis

    缓存验证 在⼀个sqlSession中,对user表根据username进⾏两次查询,查看他们发出sql语句的情况 查看控制台打印情况: 看控制台输出可以看出来,第一次执行了SQL查询,第二次直接打印的结果集,没有查询数据库。 同样是对user表进⾏两次查询,只不过两次查询之间进⾏了⼀次

    2024年02月06日
    浏览(31)
  • Mybatis 中的一级缓存与二级缓存

      缓存的意义是将用户经常查询的数据放入缓存(内存)中去,用户去查询数据的时候就不需要从磁盘(关系型数据库)中查询,直接从缓存中查询,从而提高了查询效率,解决了高并发中系统的性能问题。Mybatis中提供一级缓存与二级缓存。   Mybatis的一级缓存是一个

    2024年02月08日
    浏览(30)
  • Mybatis一级缓存和二级缓存(带测试方法)

    目录 相关导读 一、什么是缓存  二、Mabtis一级缓存 (1)测试一级缓存

    2023年04月08日
    浏览(68)
  • MyBatis缓存-提高检索效率的利器--一级缓存

    😀前言 本篇博文是关于MyBatis一级缓存的介绍使用和缓存失效情况分析,希望能够帮助到您😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉 💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博

    2024年02月14日
    浏览(32)
  • Redis缓存问题与缓存更新机制

    目录 ​编辑  一、缓存问题  1.1 缓存穿透  1.1.1 问题来源  1.1.2 解决方案  1.1.2.1 缓存空对象  1.1.2.2 使用布隆过滤器  1.2 缓存击穿  1.2.1 问题来源  1.2.2 解决方案  1.2.2.1 设置热点数据永远不过期  1.2.2.2 新增后台定时更新缓存线程(逻辑不过期)  1.2.2.3 使用分布式互斥锁

    2024年02月12日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包