mybatis缓存详解,一级缓存和二级缓存举例讲解

文章目录

  • mybatis缓存详解,一级缓存和二级缓存举例讲解
    • 1、一级缓存
      • 1.1、同一个sqlsession对象的不同mapper对象之间的缓存使用
        • debug运行查看cache缓存
      • 1.2、不同sqlsession对象下的不同mapper对象的缓存使用
        • debug运行查看cache缓存
      • 1.3、同一个sqlsession对象下一级缓存的清除
    • 2、二级缓存
      • 2.1、打开二级缓存配置
      • 2.2、相同sqlsessionFactory工厂下的不同session对象下的mapper对象开启二级缓存
      • 2.3、不同sqlsessionFactory工厂下的不同session对象下的mapper对象开启二级缓存
      • 2.4、二级缓存的清除
    • mybatis缓存总结!!!

mybatis缓存详解,一级缓存和二级缓存举例讲解

  • 为什么使用缓存?

    首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率

  • Mybatis中的一级缓存和二级缓存?

    • 一级缓存:

      它指的是mybatis中的SqlSession对象的缓存。当我们执行完查询之后,查询的结果会同时存在在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。

    • 二级缓存:

      它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessioFactory对象创建的SqlSession共享其缓存。

1、一级缓存

一级缓存是SqlSession范围的缓存,当调用SqlSession的commit(),close()等方法时,就会清空一级缓存。
在这里插入图片描述

  1. 第一次发起查询用户id为 1 的用户信息,先去找缓存中是否有id为 1 的用户信息,如果没有,从数据库查询用户信息。 得到用户信息,将用户信息存储到一级缓存中。

  2. 如果sqlSession去执行 commit操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读

  3. 第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

1.1、同一个sqlsession对象的不同mapper对象之间的缓存使用

@Testpublic void testGoCache(){SqlSession sqlSession = sessionFactory.openSession();//拥有同一个sqlsessionUserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);System.out.println("=============第一次查询============");User user1 = userMapper1.getUserById(41); //执行查询System.out.println(user1);System.out.println("=============第二次查询============");User user2 = userMapper2.getUserById(41);//执行查询?不执行System.out.println(user2);}

测试结果如下,发现:同一个sqlsession对象下的mapper对象使用同一个缓存,当第一次查询后,开启一级缓存,其他对象再进行查询时则不再执行sql语句,直接从缓存中获得数据。
在这里插入图片描述

debug运行查看cache缓存

在这里插入图片描述
在这里插入图片描述
通过查看缓存可以发现,相同sqlsession对象开启的是相同的缓存!

1.2、不同sqlsession对象下的不同mapper对象的缓存使用

@Testpublic void testNoGoCache(){SqlSession sqlSession1 = sessionFactory.openSession();SqlSession sqlSession2 = sessionFactory.openSession();//拥有不同的sqlsessionUserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);System.out.println("=============第一次查询============");User user1 = userMapper1.getUserById(41); //执行查询System.out.println(user1);System.out.println("=============第二次查询============");User user2 = userMapper2.getUserById(41);//执行查询?执行System.out.println(user2);}

运行结果如下,可以发现两次查询都执行了sql语句,说明不同sqlsession对象下的mapper对象所用的缓存是不同的缓存
在这里插入图片描述

debug运行查看cache缓存

在这里插入图片描述
在这里插入图片描述
通过查看缓存可以发现,不同sqlsession对象开启的是不同的缓存!

1.3、同一个sqlsession对象下一级缓存的清除

 @Testpublic void testNoGoCache2(){SqlSession sqlSession = sessionFactory.openSession();//拥有同一个sqlsessionUserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);System.out.println("=============第一次查询============");User user1 = userMapper1.getUserById(41); //执行查询System.out.println(user1);System.out.println("=============两次查询之间执行增删改=============");userMapper1.deleteUserById(1);sqlSession.commit();System.out.println("=============第二次查询============");User user2 = userMapper2.getUserById(41);//执行查询System.out.println(user2);}

运行结果如下,可以发现两次查询都执行了sql语句,说明两次查询中间进行commit或close操作后会清除缓存!
在这里插入图片描述

2、二级缓存

二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

二级缓存结构图:
在这里插入图片描述
在这里插入图片描述

2.1、打开二级缓存配置

1、在mybatis-config.xml 文件全局开启二级缓存

<settings><!-- 开启二级缓存的支持 --><setting name="cacheEnabled" value="true"/>
</settings>

2、配置相关的Mapper映射文件局部开启二级缓存

<mapper namespace="cn.fpl1116.dao.UserDao"><!-- 开启二级缓存的支持 --><cache></cache>

2.2、相同sqlsessionFactory工厂下的不同session对象下的mapper对象开启二级缓存

@Testpublic void testGoCache(){SqlSession sqlSession1 = sessionFactory.openSession();SqlSession sqlSession2 = sessionFactory.openSession();//拥有相同的sqlSessionFactroryUserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);System.out.println("=============第一次查询============");User user1 = userMapper1.getUserById(41); //执行sqlSystem.out.println(user1);sqlSession1.commit(); //第一次查询session执行commit或close,才会把数据写到二级缓存System.out.println("=============第二次查询============");User user2 = userMapper2.getUserById(41);//执行sql?不执行sqlSystem.out.println(user2);}

运行结果如下,可以发现和上面的一级缓存不同的是,开启二级缓存后,只要是同一个sqlsessionFactory工厂下的,不同sqlsession对象也是使用同一个二级缓存!
在这里插入图片描述
二级缓存的开启:需要第一次查询session执行commit或close,才会把数据写到二级缓存

2.3、不同sqlsessionFactory工厂下的不同session对象下的mapper对象开启二级缓存

 @Testpublic void testNoGoCache() throws IOException {//加载mybatis-config.xmlString resource = "mybatis-config.xml";InputStream inputStream1 = Resources.getResourceAsStream(resource);SqlSessionFactory sessionFactory1 = new SqlSessionFactoryBuilder().build(inputStream1);InputStream inputStream2 = Resources.getResourceAsStream(resource);SqlSessionFactory sessionFactory2 = new SqlSessionFactoryBuilder().build(inputStream2);SqlSession sqlSession1 = sessionFactory1.openSession();SqlSession sqlSession2 = sessionFactory2.openSession();//拥有不相同的sqlSessionFactroryUserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);System.out.println("=============第一次查询============");User user1 = userMapper1.getUserById(41); //执行sqlSystem.out.println(user1);sqlSession1.commit(); //第一次查询session执行commit或close,才会把数据写到二级缓存System.out.println("=============第二次查询============");User user2 = userMapper2.getUserById(41);//执行sql?执行sqlSystem.out.println(user2);}

运行结果如下,可以发现,第二次并没有使用到二级缓存中的数据,而是又一次进行了sql执行,说明不同sqlsessionFactory工厂下不是同一个二级缓存!(但一般一个项目中只有一个sqlsessionFactory工厂)
在这里插入图片描述

2.4、二级缓存的清除

 @Testpublic void testNoGoCache2(){SqlSession sqlSession1 = sessionFactory.openSession();SqlSession sqlSession2 = sessionFactory.openSession();//拥有相同的sqlSessionFactroryUserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);System.out.println("=============第一次查询============");User user1 = userMapper1.getUserById(41); //执行sqlSystem.out.println(user1);sqlSession1.commit(); //第一次查询session执行commit或close,才会把数据写到二级缓存System.out.println("=============两次查询之间执行增删改查=============");userMapper1.deleteUserById(1);sqlSession1.commit();System.out.println("=============第二次查询============");User user2 = userMapper2.getUserById(41);//执行sql?执行sqlSystem.out.println(user2);}

运行结果如下,可以发现两次查询之间执行增删改查commit会清除二级缓存!
在这里插入图片描述

mybatis缓存总结!!!

1、一级缓存范围:一级缓存范围是sqlSession配置:默认开启走缓存:同一个sqlsession执行同一条sql不走缓存:不同sqlSession 或 两次查询之间执行了增删改
2、二级缓存范围:二级缓存范围是sqlSessionFactory配置:<cache></cache>走缓存:同一个sqlSessionFactrory,sqlsession执行commit或close不走缓存:不同sqlSessionFactrory 或 两次查询之间执行了增删改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/300431.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将elementUI,NaiveUI的progress环形进度条设置为渐变色

需求 &#xff1a;进度条要有一个渐变效果。效果图&#xff1a; NaiveUI和elementUI的官方progress组件都是只能设置一种颜色&#xff0c;不符合需求所以改一下。 其实NaiveUI和elementUI设置进度条的实现方式基本一样都是使用svg渲染出两个path&#xff0c;第一个是底色&…

概率论中的 50 个具有挑战性的问题 [第 6 部分]:Chuck-a-Luck

一、说明 我最近对与概率有关的问题产生了兴趣。我偶然读到了弗雷德里克莫斯特勒&#xff08;Frederick Mosteller&#xff09;的《概率论中的五十个具有挑战性的问题与解决方案》&#xff09;一书。我认为创建一个系列来讨论这些可能作为面试问题出现的迷人问题会很有趣。每篇…

zookeeper基本使用

目录 环境搭建 单机版搭建 集群版搭建 基本语法使用 可视化客户端 数据结构 节点分类 1. 持久节点 2. 临时节点 3. 有序节点 4. 容器节点 5. TTL节点 节点状态 监听机制 watch监听 永久性watch 应用场景 1. 实现分布式锁 2. 乐观锁更新数据 应用场景总结 选…

小程序面试题 | 18.精选小程序面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

支付宝、学习强国小程序input、textarea数据双向绑定

前言 和 vue 的绑定有些区别&#xff0c;需要注意。直接 value"{{inputValue}}" 是无法双向绑定的。 正确思路 文档说的比较详细&#xff0c;不过没有组合使用的案例&#xff0c;需要自行理解。这里正确的方法是先用 value 绑定数据&#xff0c;再使用 onInput 事件…

LabVIEW在齿轮箱故障诊断中的应用

LabVIEW在齿轮箱故障诊断中的应用 在现代机械工业中&#xff0c;齿轮箱作为重要的传动设备&#xff0c;其性能稳定性对整体机械系统的运行至关重要。故障的及时诊断和处理不仅保障了设备的稳定运行&#xff0c;还减少了维护成本。利用LabVIEW强大数据处理和仿真能力&#xff0…

web前端项目-七彩夜空烟花【附源码】

web前端项目-七彩动态夜空烟花【附源码】 本项目仅使用了HTML&#xff0c;代码简单&#xff0c;实现效果绚丽&#xff0c;且本项目代码直接运行即可实现&#xff0c;无需图片素材&#xff0c;接下来让我们一起实现一场美丽的烟花秀叭 运行效果&#xff1a;鼠标点击和移动可控制…

MyBatis的缓存!!!!

为什么使用缓存&#xff1f; 首次访问时&#xff0c;查询数据库&#xff0c;并将数据存储到内存中&#xff1b;再次访问时直接访问缓存&#xff0c;减少IO、硬盘读写次数、提高效率 Mybatis中的一级缓存和二级缓存&#xff1f; 一级缓存: 它指的是mybatis中的SqlSession对象的…

WPS复选框里打对号,显示小太阳或粗黑圆圈的问题解决方法

问题描述 WPS是时下最流行的字处理软件之一&#xff0c;是目前唯一可以和微软office办公套件相抗衡的国产软件。然而&#xff0c;在使用WPS的过程中也会出现一些莫名其妙的错误&#xff0c;如利用WPS打开docx文件时&#xff0c;如果文件包含复选框&#xff0c;经常会出…

赛宁综合安全验证评估,筑牢关基网络安全屏障

在国际复杂态势和数字经济发展的驱动下&#xff0c;关键信息基础设施&#xff08;以下简称&#xff1a;关基&#xff09;的安全运营逐步走向实战化、体系化和常态化。验证评估作为安全运营的试金石&#xff0c;已成为实现动态防御、主动防御的有力手段。如何通过体系化验证评估…

vscode括号颜色突然变成白色的了,怎么解决

更新版本后发现vscode的各种括号都变成了白色&#xff0c;由于分色括号已经使用习惯&#xff0c;突然变成白色非常不舒服&#xff0c;尝试多次后&#xff0c;为大家提供一下几种解决方式&#xff0c;希望能帮到同样受到此种困惑的你&#xff1a; 第一种&#xff1a; 首先打开…

往年面试精选题目(前50道)

常用的集合和区别&#xff0c;list和set区别 Map&#xff1a;key-value键值对&#xff0c;常见的有&#xff1a;HashMap、Hashtable、ConcurrentHashMap以及TreeMap等。Map不能包含重复的key&#xff0c;但是可以包含相同的value。 Set&#xff1a;不包含重复元素的集合&#…