目录


什么是查询缓存

mybatis 在查询数据的时候,会将数据存储起来,下次再次查询相同的数据,就不会再去查询数据库,而是直接从 缓存 中查询 ;

这样达到,减轻服务器压力,提高响应 ;

mybatis 提供 一级缓存 、二级缓存 ;


图解查询缓存

  1. 一级缓存

    mybatis 在操作数据库的时候,会先创建 sqlsession ,用 sqlsession 去操作数据库 ;

    在每个 sqlsession 中,都有一个数据结构(hashmap),用于存储缓存,在不同的 sqlsession 之间,它们是相互不影响的 ;

    存储在这些 sqlsession 对象内部的缓存,就是 一级缓存

    hashmapkey 格式是 : 查询到的对象的哈希码:satement 的 id:、、: 参数value 是查询到的对象 ;

  2. 二级缓存

    当多个不同的 sqlsession 对象,去使用同一个 mapper 映射关系文件中的 sql 语句,也会产生缓存,这个缓存是跨 sqlsession 的,凡是使用同一个 mapper 映射关系文件中的 sql 语句的 sqlsession 对象都是共享这个缓存的 ;

    缓存的底层也是 hashMap


一级缓存

  1. 原理

    每次查询,会先去缓存中,检查要查询的数据,在缓存中有没有,如果有,则直接拿缓存中的数据 ;

    如果缓存中没有的话,才去查询数据库,并将查询到的数据写入缓存 ;

    如果执行过 commit 操作,则会清空 全部缓存,因为,commit 会对数据库数据进行修改,因此清空缓存,使得下次查询必须经过数据库,也就是保证数据库的缓存必须是最新的数据 ;

  2. 图示


二级缓存

  1. 原理

    当我们开启 二级缓存 的时候(默认就是开启的),查询数据的时候,是先去 一级缓存 找,没有的话,再去 二级缓存 中找,都没有的话,才会去查询数据库 ;

    当从数据库查询到信息以后,首先将查询到的数据存进 一级缓存 中,然后当 sqlsession 关闭以后,sqlsession 中的 一级缓存,才会被写入 二级缓存

    如果 sqlsession 执行了 commit 操作了,也会清空 二级缓存

  2. 图示

    注意:图中有2个地方被我画错了,复制第一个图 ,忘记修改了!!!我也不想重画了

    sqlsession B 不应该是查询,应该是进行 commit 操作 ;


  3. pojo 必须实现 序列化 接口

    因为,我们的二级缓存的 hashmap 是查询到的 pojo 对象,而我们有时候 二级缓存,并不是保存到 内存 中的,可能保存到 硬盘 上,这样就可以 反序列化

    因此,使用 二级缓存 那么 pojo 类必须实现序列化接口 ;


  4. 注意点

    二级缓存,是按照 mapper 文件的 命名空间 划分的 ,只要 命名空间 相同,则公用一份 二级缓存

    最后只要 log 文件中出现 命中率,就代表 二级缓存 开始使用了 ;

    命中率:

    Cache Hit Ratio [xin.ijava.dao.UserMapper]: 0.3333333333333333

禁用二级缓存

select 标签中配置 useCache 属性,其默认值是 true ,将其值设为 false ,就会禁用 二级缓存


刷新缓存

mybatis刷新缓存,就是直接 清空缓存 ,默认值是 true ,我们可以设置 commit 操作的属性 flushCache的值为 false 让其不刷新缓存,一般不会这样做;


二级缓存应用场景

某信息,不经常变化,其用户对该信息实时性要求不高,这时候,可以使用二级缓存 ;

比如:电话账单

用户要想查询 前一天前一个月 的电话账单,电话账单一旦产生,基本就不会再变了,除非用户删除某条通话记录 ;

并且一般,对电话账单的实时性要求也不高,基本为 0 ,营业厅给我们提供查什么时候的电话账单,我们就去查什么时候的;

比如,人家就提供了,查询前一天的电话账单,那么,我们想查今天的,只能等到明天再查今天的 ;

对于这样的信息,我们就可以使用 mybatis二级缓存 了,并且在开启具体 mapper二级缓存 的时候,配置刷新频率 flushInterval

刷新频率的时候根据需求而定,这里,人家提供查询前一天的数据,那么,我们的刷新频率,就设为 一天;这样,当我们想查询昨天的电话账单的时候,也就第一次需要去查数据库,然后,今天的任意时候,再去查询,都是直接拿 二级缓存

等到明天的时候,我们设定的刷新频率 就会自动刷新缓存,因为,之前的缓存已经没用了,现在查询前一天的数据,应该是今天的数据 ;


二级缓存局限性

其实 mybatis 的二级缓存,应用的应该不广泛 ;它有很大的局限性 ;

比如,我们缓存中已经缓存了 10000 商品价格的记录,这样 ,当这一万条商品再被访问时,就不再去查询数据库了;

但是,只要这一万条里面的任意一条商品记录发生变化,那么 剩下的 9999 条记录,都会被一并刷新掉,这样,导致命中率很低;

也就是对 细粒度 的缓存很不友好,即想要具体到某一条改变了,只刷新改变的这一条记录的缓存,留下其他的没更改的数据缓存,mybatis 是做不到的,原因在于 mybatis 自己的缓存策略,只要其中一个 sqlsession 进行 commit ,即刷新缓存 ;

对于这样的问题,我们需要在 services 自己写逻辑进行完成,也就是所谓的 三级缓存


(十二)mybatis 查询缓存的更多相关文章

  1. (十二)数据库查询处理之Query Execution(1)

    (十二)数据库查询处理之Query Execution(1) 1. 写在前面 这一大部分就是为了Lab3做准备的 每一个query plan都要实现一个next函数和一个init函数 对于next函数 ...

  2. Mybatis学习记录(七)----Mybatis查询缓存

    1. 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sql ...

  3. 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合

    1       查询缓存 1.1     什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.

  4. mybatis查询缓存——(十三)

    1.     mybatis缓存介绍 如下图,是mybatis一级缓存和二级缓存的区别图解: mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.

  5. (十)mybatis之缓存

    一.缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)去查询,从缓存中进行查询,从而提高查询效率,解决了高并发系统的性能问题. 二.mybatis ...

  6. Spring+SpringMVC+MyBatis深入学习及搭建(八)——MyBatis查询缓存

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6956206.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(七)——My ...

  7. apache ignite系列(九):使用ddl和dml脚本初始化ignite并使用mybatis查询缓存

    博客又断了一段时间,本篇将记录一下基于ignite对jdbc支持的特性在实际使用过程中的使用. 使用ddl和dml脚本初始化ignite 由于spring-boot中支持通过spring.dataso ...

  8. 让EFCore更疯狂些的扩展类库(二):查询缓存、分部sql、表名替换的策略配置

    前言 上一篇介绍了扩展类库的功能简介,通过json文件配置sql语句 和 sql语句的直接执行,这篇开始说明sql配置的策略模块:策略管理器与各种策略的配置. 类库源码:github:https:// ...

  9. mybatis 查询缓存问题

    <settings> <setting name="localCacheScope" value="STATEMENT" /> < ...

随机推荐

  1. python实现随机生成头像

    今天遇到如何给用户分配随机头像的问题,想着要在本地放很多图片,有点无聊,就找了一些生成头像的工具.发现gravatar生成图像还不错,挺好玩的. 1.下面上代码 # -*- coding: utf-8 ...

  2. Robot Framework(十九) 附录

    6附录 6.1测试数据中的所有可用设置 6.1.1设置表 Setting表用于导入测试库,资源文件和变量文件,以及定义测试套件和测试用例的元数据.它可以包含在测试用例文件和资源文件中.请注意,在资源文 ...

  3. flask 中扩展 flask-login

  4. Java并发指南2:深入理解Java内存模型JMM

    本文转载自互联网,侵删   一:JMM基础与happens-before 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实 ...

  5. pwn学习日记Day9 基础知识积累

    知识杂项 libc是Linux下的ANSI C的函数库. LOOKUP函数 数组形式:公式为= LOOKUP(lookup_value,array) 式中 array-包含文本.数字或逻辑值的单元格区 ...

  6. 冲刺阶段——Day2

    [今日进展] 完成黄金点游戏的算法与代码架构. 使用文字界面完成任务 码云链接:https://gitee.com/jxxydwt1999/20175215-java/blob/master/Gold ...

  7. 黑马vue---28、vue中全局过滤器的基本使用

    黑马vue---28.vue中全局过滤器的基本使用 一.总结 一句话总结: vue中的过滤器可以传递参数(根据参数来过滤),也可以用管道符拼接多个过滤器:例如<p>{{ msg | msg ...

  8. kvm安装及简单使用

    1 cat /etc/redhat-release      CentOS release 6.4 (Final)2 egrep ‘vmx|svm’ /proc/cpuinfo3 yum -y ins ...

  9. python笔记5 接口类抽象类 封装 反射 设计模式 模块 :random随机数 josn shelve持久化存储

    接口类抽象类 接口类:接口类就是制定一个规则,让其他人按照我的规则去写程序. #!/usr/bin/env python from abc import ABCMeta,abstractmethod ...

  10. strace调试跟踪程序运行状态

    查看进程调用和执行状态  :   strace  -f -F  -o debug.log  -p   PID(某个进程ID) 参考资料: http://www.itshouce.com.cn/linu ...