目录

  • 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

    • 与数据同一次会话期间查询到的数据会放到本地缓存中
    • 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库

测试步骤

  1. 开启日志, 方便查看执行了几次SQL

    <settings><!--默认的日志工厂--><setting name="logImpl" value="STDOUT_LOGGING"/></settings>
    
  2. 在一次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();
    }
    
  3. 查看日志输出结果可以看到执行了几次SQL

缓存失效的情况

  • 查询不同的东西

  • 增删改操作可能会改变原来的数据, 所以必定会刷新缓存

  • 查询不同的 Mapper.xml

  • 手动清除缓存:sqlSession.clearCache();

  1. 增删改操作可能会改变原来的数据, 所以必定会刷新缓存
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)中;

开启步骤

  1. 开启全局缓存(默认就是开启的)
<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
  1. 在要使用二级缓存的 Mapper.xml 中开启缓存
<!--在当前 Mapper.xml 中使用二级缓存-->
<cache/>

也可以自定义参数开启缓存

<cacheeviction="FIFO"flushInterval="60000"size="512"readOnly="true"/>
  1. 测试

    1. 我们需要将实体类序列化, 否则可能会报一个错

      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 下就有效
  • 所有的数据都会先放在一级缓存中, 只有当会话提交或者关闭的时候, 才会提交到二级缓存中去

缓存原理

缓存顺序

  1. 先看二级缓存中有没有, 有就直接返回, 没有就往下走
  2. 再看一级缓存中有没有, 有就直接返回, 没有就往下走
  3. 再去查询数据库, 将查询结果放到一级缓存中
  4. 如果一级缓存的 SqlSession 提交或者关闭, 会将一级缓存中数据提交到二级缓存

Mybatis 一级缓存和二级缓存的使用相关推荐

  1. Mybatis一级缓存,二级缓存的实现就是这么简单

    介绍 又到了一年面试季,所以打算写一点面试常问的东西,争取说的通俗易懂.面试高级岗,如果你说熟悉Mybatis,下面这些问题基本上都会问 Mybatis插件的实现原理? 如何写一个分页插件? Myba ...

  2. mybatis高级(3)_延迟加载_深度延迟_一级缓存_二级缓存

    设置延迟加载需要在mybatis.xml中设置 注: 侵入式延迟加载为真时是延迟加载 侵入式延迟加载为假时是深度延迟加载 <!-- 延迟加载和深度延迟加载 --><settings& ...

  3. MyBatis框架:延迟加载策策略、一级缓存、二级缓存

    MyBatis框架:延迟加载策略和缓存 Mybatis 延迟加载策略 1.1 何为延迟加载? 1.2 实现需求 1.3 使用association实现延迟加载 1.3.1 账户的持久层DAO接口 1. ...

  4. 浅谈Mybatis的一级缓存和二级缓存

    MyBatis的缓存机制 缓存的引入 当我们大量执行重复的查询SQL语句的时候,会频繁的和数据库进行通信,会增加查询时间等影响用户体验的问题,可以通过缓存,以降低网络流量,使网站加载速度更快. MyB ...

  5. MyBatis】MyBatis一级缓存和二级缓存

    转载自  MyBatis]MyBatis一级缓存和二级缓存 MyBatis自带的缓存有一级缓存和二级缓存 一级缓存 Mybatis的一级缓存是指Session缓存.一级缓存的作用域默认是一个SqlSe ...

  6. Mybatis 详解--- 一级缓存、二级缓存

    2019独角兽企业重金招聘Python工程师标准>>> Mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSession级别的缓存.在操作数据 ...

  7. Mybatis源码分析之(七)Mybatis一级缓存和二级缓存的实现

    文章目录 一级缓存 二级缓存 总结 对于一名程序员,缓存真的很重要,而且缓存真的是老生常谈的一个话题拉.因为它在我们的开发过程中真的是无处不在.今天LZ带大家来看一下.Mybatis是怎么实现一级缓存 ...

  8. 框架源码专题:Mybatis的一级缓存、二级缓存是什么?有什么作用?

    文章目录 1. Mybatis中缓存的作用 2. 一级缓存 3. 二级缓存 4. 一级缓存和二级缓存的区别 5. 通过代码观察Mybatis缓存工作的全过程 1. Mybatis中缓存的作用 首先缓存 ...

  9. MyBatis中的一级缓存和二级缓存介绍

    先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能. 一级缓存 一级 ...

  10. mybatis 详解------ 一级缓存、二级缓存(九)

    mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSession级别的缓存.在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMa ...

最新文章

  1. Aurora的安装和中文配置
  2. RHEL5.1安装VM TOOL及中文乱码终极解决方案
  3. php 将图片截取成3张,【php】php gd库怎么把一个图片裁剪成圆形的
  4. 2015年企业如何避免索尼式的安全悲剧?
  5. 一个方法搞定安卓路由跳转
  6. 硬中断、软中断和信号
  7. Android如何把 内容复制到剪贴板
  8. 中video拖动_【小功能】UE4中实现UI的拖拽
  9. 华为荣耀5cvs华为v9play_华为荣耀v9play和荣耀9哪个好_华为荣耀v9play和荣耀9对比评测_飞翔教程...
  10. 如何格式化电脑_移动硬盘提示格式化如何解决?数据恢复软件解决问题
  11. C语言实现1~100的和(三种循环)
  12. 云效 > 产品简介 > 产品概述
  13. 201409-3-字符串匹配
  14. 浅谈虚拟桌面上线推广的最佳时机
  15. SM2算法加密与解密过程
  16. springboot整合银联支付B2C
  17. iphone屏幕镜像如何全屏_苹果手机投到电视上能全屏嘛 具体怎样投屏呢
  18. 纳韦斯托克斯方程的推导_纳维-斯托克斯方程(N-S方程)详细推导.ppt
  19. matlab iir滤波器系数,5.IIR数字滤波器
  20. HSV色彩空间筛选 2021-10-06

热门文章

  1. java 递归 返回值不准确 出栈覆盖的问题
  2. 1分钟链圈 | 以太坊2.0 Casper 更新版发布,涉及解决跨分片通信低效问题
  3. big data characteristics and workflow
  4. Windows 10下麦克风无法使用的情况
  5. NFC的读写实现--高上
  6. 前端三大技术栈之CSS3总结上
  7. 【BZOJ】2820: YY的GCD
  8. rkhunter(rootkit检测)
  9. Linux fork隐藏的开销-过时的fork(正传)
  10. windows 和 ubuntu 下 git + svn 客户端