一、缓存的意义

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

二、mybatis持久层缓存

  • mybatis一级缓存是一个Sqlsession级别,SqlSession只能访问自己的一级缓存数据,二级缓存是跨SqlSession的,是mapper级别的缓存,对于mapper级别的缓存 不同的SqlSession是可以共享的。

三、一级缓存

  3.1  原理

  • 流程:  第一次发出sql语句查询id为1的用户时,sql查询的结果写入sqlSession一级缓存中,缓存使用的数据结构是一个map<key,value>
key: hashcode+sql+sql输入参数+sql输出参数 (作为SQL的唯一标识)

value: 用户信息。

同一个sqlSession再次发出相同的sql,就从缓存中取数据,不再查询数据库。如果两次中间出现commit操作(修改、添加、删除),此SqlSession中的一级缓存数据全部清空,下次再去缓存中就会查询不到数据再从数据库查询,从数据库查询到后再写入缓存。
每次查询都先从缓存进行查询。
注意:清空时会清空当前sqlsession缓存区域中的全部内容。

  3.2  一级缓存配置

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

四、二级缓存

  4.1  二级缓存原理

  • 二级缓存的范围是mapper级别(mapper同一个命名空间),mapper以命名空间为单位创建缓存数据结构,结构为map<key,value>
   每次查询先看是否开启二级缓存,如果开启先从二级缓存中数据结构中取缓存数据。
     如果从二级缓存中没有取到,再从一级缓存中进行查找,如果一级缓存也没有,从数据库查询。

  4.2  mybatis二级缓存配置

  • mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,即:<setting name="cacheEnabled" value="true"/>

,还要在具体的mapper.xml中开启二级缓存,即:

  1. <mapper namespace="com.shyroke.mapper.OrderMapper">
  2.   <cache />
  3. </mapper>

  4.3  注意

  • mybatis二级缓存需要将查询结果映射的pojo实现 java.io.serializable接口,如果不实现则抛出异常:org.apache.ibatis.cache.CacheException: Error serializing object.  Cause: java.io.NotSerializableException
  • 二级缓存可以将内存中的数据写到硬盘,存在对象的序列和反序列化,所以要实现java.io.serializable接口。如果结果映射的pojo中还关联了别的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操作,对二级缓存进行刷新(全局清空)
设置与commit相关statement(insert,update,delete等标签)的flushCache属性是否刷新缓存,默认值是true,如果设置了为false,即使后台数据库发生了变化,只要缓存没有过期,也只会读取缓存中数据 就会获取不到最新数据。

  4.6 测试

  1. public static void main(String[] args) throws IOException {
  2. String resource = "resource/mybatis-config.xml";
  3. InputStream inputStream = Resources.getResourceAsStream(resource);
  4. SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  5.  
  6. SqlSession session = sessionFactory.openSession();
  7. SqlSession session2 = sessionFactory.openSession();
  8.  
  9. OrderMapper orderMapper = session.getMapper(OrderMapper.class);
  10. OrderMapper orderMapper2 = session2.getMapper(OrderMapper.class);
  11.  
  12. Customer customer=orderMapper.findCustomerById(1);
  13. System.out.println(customer);
  14.  
  15. //关闭session,将信息写入二级缓存中
  16. session.close();
  17.  
  18. Customer customer2=orderMapper2.findCustomerById(1);
  19. System.out.println(customer2);
  20.  
  21. }
  • 注意:只有关闭sqlSession的时候,才会把信息写入二级缓存中。

  4.7  mybatis自带的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 – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

五、番外

  • 二级缓存的应用场景

对于查询频率高,变化频率低的数据建议使用二级缓存。
对于访问多的查询请求且用户对查询结果的实时性要求不高,此时可采用mybatis二级缓存技术降低数据库的访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。
实现方法如下:通过设置刷新时间间隔,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新时间间隔flushInterval,比如设置30分钟、60分钟、24小时等,根据需求而定。
 
  • mybatis局限性

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

(十)mybatis之缓存的更多相关文章

  1. MyBatis基础入门《十六》缓存

    MyBatis基础入门<十六>缓存 >> 一级缓存 >> 二级缓存 >> MyBatis的全局cache配置 >> 在Mapper XML文 ...

  2. Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存

    本片文章续<Spring Boot 入门(九):集成Quartz定时任务>.本文主要基于redis实现了mybatis二级缓存.较redis缓存,mybaits自带缓存存在缺点(自行谷歌) ...

  3. Mybatis 一级缓存和二级缓存原理区别 (图文详解)

    Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别@mikechen Mybatis缓存 缓存就是内存中的数据,常常来自对数据库查询结 ...

  4. 通过源码分析MyBatis的缓存

    前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...

  5. MyBatis 一级缓存与二级缓存

    MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3. ...

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

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

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

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

  8. MyBatis一级缓存引起的无穷递归

    MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...

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

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

随机推荐

  1. linux下 安装 ImageMagick 及其 php imagick扩展(转)

    linux下 安装 ImageMagick 及其 php imagick扩展 PHP版本7.1.3 : ImageMagick版本 ImageMagick-7.0.8-3: PHP扩展imagick版 ...

  2. [IMX6DL] CPU频率调节模式以及降频方法

    本文转自http://blog.csdn.net/kris_fei/article/details/51822435 Kernel branch: 3.0.35 CPU的频率调节模式:1. Perfo ...

  3. KDChart example

    /******************************************************************************** ** Form generated ...

  4. Django中的文件上传和原生Ajax

    概述 Django中的上传有3种方案: form 表单常规上传,但点击提交后会自动刷新页面 Ajax 上传,不刷新页面,(分为原生ajax上传和jQuery上传),IE7以上不兼容 iframe 上传 ...

  5. PAT 甲级 1040 Longest Symmetric String (25 分)(字符串最长对称字串,遍历)

    1040 Longest Symmetric String (25 分)   Given a string, you are supposed to output the length of the ...

  6. 【linux基础】Ubuntu下的终端多标签切换快捷键

    method: 方法一: alt+ alt+ alt+ 方法二: ctrl + pageUp ctrl + pageDown 方法三: Edit--> Keybord Shortcuts 到这里 ...

  7. 记一次线上由nginx upstream keepalive与http协议"协作"引起的接口报错率飙高事件

    年前接到个任务,说要解决线上一些手机客户端接口报错率很高的问题.拿到了监控邮件,粗略一看,各种50%+的错误率,简直触目惊心.这种疑难杂症解决起来还是挺好玩的,于是撸起袖子action. 最终的结果虽 ...

  8. conda安装的国内镜像配置,实现快速下载

    conda安装的国内镜像配置,实现快速下载 anaconda的所有的软件包全部在国外,安装起来很麻烦,关键是下载速度慢,而且经常中断,所以需要配置国内安装的镜像,下载速度就很快了. 一.conda换国 ...

  9. 原装win8系统电脑崩溃问题解决

    原装win8系统电脑崩溃问题解决 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:之所以撰写本篇关于win8原装系统电脑崩溃的博文,一是要吐槽一下原装w ...

  10. abp(net core)+easyui+efcore

    abp(net core)+easyui+efcore实现仓储管理系统——展现层实现增删改查之控制器(六)   abp(net core)+easyui+efcore实现仓储管理系统目录 abp(ne ...