Mybatis 一级缓存和二级缓存的使用
目录
- Mybatis缓存
- 一级缓存
- 二级缓存
- 缓存原理
Mybatis缓存
官方文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache
MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制
Mybatis中默认定义了两级缓存:一级缓存和二级缓存
- 默认情况下,只启用了一级缓存(sqlSession级别的缓存),它仅仅对一个会话中的数据进行缓存。
- 二级缓存需要手动开启和配置,它是基于 namespace级别的缓存
- 为了提高扩展性,Mybatis定义了缓存接口 Cache,我们可以通过实现Cache接口来自定义二级缓存
Mybatis缓存策略,可用的清除策略有:
LRU
– 最近最少使用:移除最长时间不被使用的对象。FIFO
– 先进先出:按对象进入缓存的顺序来移除它们。SOFT
– 软引用:基于垃圾回收器状态和软引用规则移除对象。WEAK
– 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRU。
一级缓存
一级缓存默认是开启的, 只在一次 sqlSession 中有效, 就是从拿到到关闭的这个区间
- 一级缓存也叫本地缓存: SqlSession
- 与数据同一次会话期间查询到的数据会放到本地缓存中
- 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
测试步骤
开启日志, 方便查看执行了几次SQL
<settings><!--默认的日志工厂--><setting name="logImpl" value="STDOUT_LOGGING"/></settings>
在一次sqlSession中查询两次相同的记录
public void getUserById() {SqlSession sqlSession = MybatisUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = mapper.getUserById(1);System.out.println(user);System.out.println("========================");User userById = mapper.getUserById(1);System.out.println(userById);System.out.println(user == userById); // truesqlSession.close(); }
查看日志输出结果可以看到执行了几次SQL
缓存失效的情况
查询不同的东西
增删改操作可能会改变原来的数据, 所以必定会刷新缓存
查询不同的 Mapper.xml
手动清除缓存:
sqlSession.clearCache();
- 增删改操作可能会改变原来的数据, 所以必定会刷新缓存
public void getUserById() {SqlSession sqlSession = MybatisUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 查询 1 号User user = mapper.getUserById(1);System.out.println(user);// 修改 2 号int i = mapper.updateUser(new User(2, "aaa", "bbb"));System.out.println("========================");// 再次查询 1 号User userById = mapper.getUserById(1);System.out.println(userById);System.out.println(user == userById); // falsesqlSession.close();
}
二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容;
- 不同的mapper查出的数据会放在自己对应的缓存(map)中;
开启步骤
- 开启全局缓存(默认就是开启的)
<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
- 在要使用二级缓存的 Mapper.xml 中开启缓存
<!--在当前 Mapper.xml 中使用二级缓存-->
<cache/>
也可以自定义参数开启缓存
<cacheeviction="FIFO"flushInterval="60000"size="512"readOnly="true"/>
测试
我们需要将实体类序列化, 否则可能会报一个错
Cause: java.io.NotSerializableException: com.pro.pojo.User
public void getUserById2() {SqlSession sqlSession = MybatisUtils.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 查询 1 号, 会先放到一级缓存中User user = mapper.getUserById(1);System.out.println(user);// sqlSession 关闭, 将一级缓存中数据提交到二级缓存中sqlSession.close();SqlSession sqlSession2 = MybatisUtils.getSqlSession();UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);// 再次查询 1 号User userById = mapper2.getUserById(1);System.out.println(userById);System.out.println(user == userById); // falsesqlSession2.close();
}
小结
- 只要开启来二级缓存, 同一个 Mapper 下就有效
- 所有的数据都会先放在一级缓存中, 只有当会话提交或者关闭的时候, 才会提交到二级缓存中去
缓存原理
缓存顺序
- 先看二级缓存中有没有, 有就直接返回, 没有就往下走
- 再看一级缓存中有没有, 有就直接返回, 没有就往下走
- 再去查询数据库, 将查询结果放到一级缓存中
- 如果一级缓存的 SqlSession 提交或者关闭, 会将一级缓存中数据提交到二级缓存
Mybatis 一级缓存和二级缓存的使用相关推荐
- Mybatis一级缓存,二级缓存的实现就是这么简单
介绍 又到了一年面试季,所以打算写一点面试常问的东西,争取说的通俗易懂.面试高级岗,如果你说熟悉Mybatis,下面这些问题基本上都会问 Mybatis插件的实现原理? 如何写一个分页插件? Myba ...
- mybatis高级(3)_延迟加载_深度延迟_一级缓存_二级缓存
设置延迟加载需要在mybatis.xml中设置 注: 侵入式延迟加载为真时是延迟加载 侵入式延迟加载为假时是深度延迟加载 <!-- 延迟加载和深度延迟加载 --><settings& ...
- MyBatis框架:延迟加载策策略、一级缓存、二级缓存
MyBatis框架:延迟加载策略和缓存 Mybatis 延迟加载策略 1.1 何为延迟加载? 1.2 实现需求 1.3 使用association实现延迟加载 1.3.1 账户的持久层DAO接口 1. ...
- 浅谈Mybatis的一级缓存和二级缓存
MyBatis的缓存机制 缓存的引入 当我们大量执行重复的查询SQL语句的时候,会频繁的和数据库进行通信,会增加查询时间等影响用户体验的问题,可以通过缓存,以降低网络流量,使网站加载速度更快. MyB ...
- MyBatis】MyBatis一级缓存和二级缓存
转载自 MyBatis]MyBatis一级缓存和二级缓存 MyBatis自带的缓存有一级缓存和二级缓存 一级缓存 Mybatis的一级缓存是指Session缓存.一级缓存的作用域默认是一个SqlSe ...
- Mybatis 详解--- 一级缓存、二级缓存
2019独角兽企业重金招聘Python工程师标准>>> Mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSession级别的缓存.在操作数据 ...
- Mybatis源码分析之(七)Mybatis一级缓存和二级缓存的实现
文章目录 一级缓存 二级缓存 总结 对于一名程序员,缓存真的很重要,而且缓存真的是老生常谈的一个话题拉.因为它在我们的开发过程中真的是无处不在.今天LZ带大家来看一下.Mybatis是怎么实现一级缓存 ...
- 框架源码专题:Mybatis的一级缓存、二级缓存是什么?有什么作用?
文章目录 1. Mybatis中缓存的作用 2. 一级缓存 3. 二级缓存 4. 一级缓存和二级缓存的区别 5. 通过代码观察Mybatis缓存工作的全过程 1. Mybatis中缓存的作用 首先缓存 ...
- MyBatis中的一级缓存和二级缓存介绍
先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能. 一级缓存 一级 ...
- mybatis 详解------ 一级缓存、二级缓存(九)
mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSession级别的缓存.在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMa ...
最新文章
- Aurora的安装和中文配置
- RHEL5.1安装VM TOOL及中文乱码终极解决方案
- php 将图片截取成3张,【php】php gd库怎么把一个图片裁剪成圆形的
- 2015年企业如何避免索尼式的安全悲剧?
- 一个方法搞定安卓路由跳转
- 硬中断、软中断和信号
- Android如何把 内容复制到剪贴板
- 中video拖动_【小功能】UE4中实现UI的拖拽
- 华为荣耀5cvs华为v9play_华为荣耀v9play和荣耀9哪个好_华为荣耀v9play和荣耀9对比评测_飞翔教程...
- 如何格式化电脑_移动硬盘提示格式化如何解决?数据恢复软件解决问题
- C语言实现1~100的和(三种循环)
- 云效 > 产品简介 > 产品概述
- 201409-3-字符串匹配
- 浅谈虚拟桌面上线推广的最佳时机
- SM2算法加密与解密过程
- springboot整合银联支付B2C
- iphone屏幕镜像如何全屏_苹果手机投到电视上能全屏嘛 具体怎样投屏呢
- 纳韦斯托克斯方程的推导_纳维-斯托克斯方程(N-S方程)详细推导.ppt
- matlab iir滤波器系数,5.IIR数字滤波器
- HSV色彩空间筛选 2021-10-06