MyBatis之查询缓存

2017/09/30

正如大多数持久层框架一样,MyBatis同样也提供了对查询数据的缓存支持。今后我们要学习的SpringMVC框架属于系统控制层,它也有它的缓存区域,对响应的jsp页面进行缓存;Spring属于系统业务层,它的缓存区域对业务数据进行缓存。而它们三者的缓存区域都存在于用户要访问数据库的中间,当用户向数据库中发送查询请求时,系统会先在它们三者的缓存区域看是否有满足用户要求的查询数据,若有则直接从缓存区域返回信息;若没有则从数据库中进行查询。

1.缓存的意义

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

2.MyBatis持久层缓存

MyBatis提供了一级缓存和二级缓存,概念图如下:

如图中所示,MyBatis一级缓存是一个SqlSession级别,SqlSession只能访问自己的一级缓存的数据,二级缓存是跨SqlSession,是mapper级别的缓存,对于mapper级别的缓存不同的Sqlsession是可以共享的。

3.MyBatis一级缓存

3.1原理

对于图的解释:第一次发出一个查询sql,sql查询结果写入sqlsession的一级缓存中,缓存使用的数据结构是一个map<key,value>

key:hashcode+sql+sql输入参数+输出参数(sql的唯一标识)
value:用户信息

同一个sqlsession再次发出相同的sql,就从缓存中取,而不走数据库。如果两次中间出现commit操作(修改、添加、删除),本sqlsession中的一级缓存区域全部清空,下次再去缓存中查询不到所以要从数据库查询,从数据库查询到再写入缓存。即对于查询操作,每次查询都先从缓存中查询,如果缓存中查询到数据则将缓存数据直接返回,如果缓存中查询不到就从数据库查询。

3.2一级缓存配置

mybatis默认支持一级缓存不需要配置。

注意:mybatis和spring整合后进行mapper代理开发,不支持一级缓存,mybatis和spring整合,spring按照mapper的模板去生成mapper代理对象,模板中在最后统一关闭sqlsession。

3.3一级缓存的测试

测试代码:

运行,在控制台看到输出:

发现打印两次结果只有第一次向数据库中发送了查询请求,第二次是直接从缓存中返回的数据。接下来我们在中间加入更新数据的操作:

然后在控制台中看到打印过程:

可以发现向数据库发送了三次请求。

4.MyBatis二级缓存

4.1二级缓存原理

二级缓存的范围是mapper级别(mapper同一个命名空间),mapper以命名空间为单位创建缓存数据结构,结构是map<key、value>

过程:每次查询先看是否开启二级缓存,如果开启从二级缓存的数据结构中取缓存数据,如果从二级缓存没有取到,再从一级缓存中找,如果一级缓存也没有,从数据库查询。

4.2二级缓存的配置

不像一级缓存那样mybatis自动开启一级缓存,mybatis是默认关闭二级缓存的,所以我们需要需要进行两个操作才能开启二级缓存:

1.在核心配置文件SqlMapperConfig.xml中加入

属性值cacheEnabled表示对在此配置文件下的所有cache 进行全局性开/关设置,它的可选值为true|false,默认值为true.

2.在你的Mapper映射文件中添加一行:<cache /> ,表示此mapper开启二级缓存。

4.3查询结果映射的pojo序列化

mybatis二级缓存需要将查询结果映射的pojo实现 java.io.serializable接口,如果不实现则抛出异常:
org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: cn.itcast.mybatis.po.User

二级缓存可以将内存的数据写到磁盘,存在对象的序列化和反序列化,所以要实现java.io.serializable接口。

如果结果映射的pojo中还包括了pojo,都要实现java.io.serializable接口。

4.4二级缓存的禁用

对于变化频率较高的sql,需要禁用二级缓存:在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

4.5刷新缓存

将二级缓存进行刷新操作有两种方式:

  • 如果sqlsession操作commit操作,对二级缓存进行刷新(全局清空)。
  • 设置statement的flushCache是否刷新缓存,默认值是true。

4.6测试代码

分别将中间更新用户信息的代码注释:发现两次打印用户信息的操作只向数据库中发送一次查询请求;去掉注释:三次操作向数据库中发送三次请求。

4.7mybatis的cache参数(了解)

mybatis的cache参数只适用于mybatis维护缓存。

  • flushInterval(刷新间隔):可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
  • size(引用数目):可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
  • readOnly(只读):属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

如下例子:

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:

  • LRU – 最近最少使用的:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

4.8二级缓存的应用场景

对查询频率高,变化频率低的数据建议使用二级缓存。

对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。

实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。

4.9二级缓存的局限性

mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。

5.MyBatis和ehcache缓存框架整合

5.1分布缓存

将缓存数据进行分布式管理,这个概念我们以后会学

5.3MyBatis和ehcache整合思路

通过MyBatis和ehcache框架进行整合,就可以把缓存数据的管理托管给ehcache。

首先我们看看MyBatis自己的二级缓存,它在自己内部提供了一个cache接口,我们只要实现了cache接口就可以把缓存数据灵活的管理起来。

要将MyBatis和ehcache整合,我们首先需要下载ehcache的jar包:

  • ehcache-core.jar
  • mybatis-ehcache.jar

然后需要添加一个ehcache的配置文件ehcache.xml:

然后在mapper.xml中添加ehcache的配置:

然后便可以进行测试。

学完以上7篇文章,你就可以使用MyBatis去搭建一个项目了.

MyBatis之查询缓存相关推荐

  1. mybatis教程--查询缓存(一级缓存二级缓存和整合ehcache)

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

  2. java元婴期(25)----java进阶(mybatis(4)---高级映射查询缓存)

    1.需要用到的数据模型(这是后面高级查询需要用到的实例) 用户表user:          记录了购买商品的用户信息 订单表:orders          记录了用户所创建的订单(购买商品的订单) ...

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

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

  4. mybatis中的查询缓存

    转载自:https://www.cnblogs.com/zhangzongle/p/6211285.html 查询缓存 Mybatis提供查询缓存,用于减轻数据压力,提高数据库压力. Mybatis提 ...

  5. 查询缓存---Mybatis学习笔记(十)

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

  6. 【MyBatis框架】查询缓存-一级缓存原理

    查询缓存 1.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 缓存模式图如图 一级缓存是SqlSession级别的缓存.在操作 ...

  7. MyBatis查询缓存

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

  8. Mybatis延迟加载和查询缓存

    一.延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 延迟加载:先 ...

  9. MyBatis延迟加载和缓存(4)

    一.项目创建 1.项目目录结构 2.数据库配置和上一篇的一样,这里不再描述.下面创建mybatis配置文件SqlMapConfig.xml 1 <?xml version="1.0&q ...

最新文章

  1. AQS基础——多图详解CLH锁的原理与实现
  2. 精读《Epitath 源码 - renderProps 新用法》
  3. 修改meta标签 查看源码没效果怎么办_Spring 源码学习(三)-自定义标签
  4. mysql的limit有什么缺陷_mysql中使用limit时,explain带来的问题分析
  5. Jmeter在运行结果中文出现乱码问题
  6. AT4119-[ARC096C]Everything on It【斯特林数,容斥】
  7. opengl计算帧率_或许是迄今为止第一篇讲解 fps 计算原理的文章吧
  8. Shell字符串比较(等于、不等于、大于、小于、起始字符、结尾字符)
  9. LeetCode-MySQL-175. 组合两个表
  10. 【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
  11. Spring实现多数据源配置
  12. 搭建自己的企业QQ [2007年6月15日]
  13. 计算机审计简答题,审计简答题总结.doc
  14. 【2020年】Android开发学习思考及规划
  15. 如何在Mac上合并照片库?
  16. MySQL数据分析实战-朱元禄-专题视频课程
  17. html a5 尺寸,纸型尺寸大小(A1,A2,A3,A4,A5,A6,B1,B2,B3,B4,B5......)
  18. BPM实例分享——金额规则大写
  19. BZOJ5109:[CodePlus 2017]大吉大利,晚上吃鸡! (最短路+Hash表+二进制压位)
  20. 【Cocos Creator 实战】01 - 如何做一款简单的拼图游戏

热门文章

  1. 5gh掌上云计算认证不通过_阿里云ACP认证考试攻略、考试心得、费用及常见问题...
  2. rmse多少算效果好_关键词SEO优化带来流量有多少?如何做SEO优化效果好?
  3. IOC操作Bean管理XML方式(注入空值和特殊符号)
  4. python电脑编程求圆的面积案例_学Python划重点七 网络编程(UPD Socket编程、上传文件实例、计算圆的面积实例)...
  5. qsub 指定节点_PBS,QSUB常用命令
  6. python整形怎么切片_python 切片操作 slice
  7. c语言文件读写r 的作用,C语言 读写二进制文件
  8. 打开git界面_使用 Gitea 快速搭建私有 Git 版本控制服务
  9. 用纸筒做机器人_365天,每天都可以玩出新花样,卷纸筒就是这么牛的神器!
  10. python适用的操作系统是_操作系统先来先服务python