前言

1、缓存:cache

2、缓存的作用:

通过减少IO(读写)的方式,来提高程序的执行效率。

3、mybatis的缓存:

将select语句的查询结果放到缓存(内存)当中,下一次还是这条select语句的话,直接从缓存中取,不再查数据库。一方面是减少了IO。另一方面不再执行繁琐的查找算法。效率大大提升。

4、mybatis缓存包括:

  • 一级缓存:将查询到的数据存储到SqlSession中。(当前的一次会话)
  • 二级缓存:将查询到的数据存储到SqlSessionFactory中。(整个数据库、环境级别的)
  • 或者集成其它第三方的缓存:比如EhCache【Java语言开发的】、Memcache【C语言开发的】等。

缓存只针对于DQL语句,也就是说缓存机制只对应select语句。

一、一级缓存

一级缓存默认是开启的。不需要做任何配置。

原理:只要使用同一个SqlSession对象执行同一条SQL语句,就会走缓存。

模块名:继续用之前的mybatis-008-select

1、CarMapper接口

package com.powernode.mybatis.mapper;import com.powernode.mybatis.pojo.Car;public interface CarMapper {/*** 根据id获取Car信息。* @param id* @return*/Car selectById1(Long id);
}

2、CarMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.powernode.mybatis.mapper.CarMapper"><select id="selectById" resultType="Car">select * from t_car where id = #{id}</select></mapper>

3、CarMapperTest

package com.powernode.mybatis.test;import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;public class CarMapperTest {@Testpublic void testSelectById() throws Exception{// 注意:不能使用我们封装的SqlSessionUtil工具类。SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);Car car1 = mapper1.selectById(83L);System.out.println(car1);CarMapper mapper2 = sqlSession1.getMapper(CarMapper.class);Car car2 = mapper2.selectById(83L);System.out.println(car2);SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper3 = sqlSession2.getMapper(CarMapper.class);Car car3 = mapper3.selectById(83L);System.out.println(car3);CarMapper mapper4 = sqlSession2.getMapper(CarMapper.class);Car car4 = mapper4.selectById(83L);System.out.println(car4);}
}

4、查看执行结果

5、什么情况下不走缓存?

  • 第一种:不同的SqlSession对象。
  • 第二种:查询条件变化了。

6、一级缓存失效情况包括两种:

  • 第一种:第一次查询和第二次查询之间,手动清空了一级缓存。
sqlSession.clearCache();
  • 第二种:第一次查询和第二次查询之间,执行了增删改操作。【这个增删改和哪张表没有关系,只要有insert delete update操作,一级缓存就失效。】

①、CarMapper接口

/**
* 保存账户信息
*/
void insertAccount();

②、CarMapper.xml

<insert id="insertAccount">insert into t_act values(3, 'act003', 10000)
</insert>

③、CarMapperTest

 public void testSelectById1() throws Exception{// 注意:不能使用我们封装的SqlSessionUtil工具类。SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);Car car1 = mapper1.selectById(8L);System.out.println(car1);mapper1.insertAccount();CarMapper mapper2 = sqlSession1.getMapper(CarMapper.class);Car car2 = mapper2.selectById(8L);System.out.println(car2);SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper3 = sqlSession2.getMapper(CarMapper.class);Car car3 = mapper3.selectById(8L);System.out.println(car3);CarMapper mapper4 = sqlSession2.getMapper(CarMapper.class);Car car4 = mapper4.selectById(8L);System.out.println(car4);}

④、查看运行结果

二、二级缓存

二级缓存的范围是SqlSessionFactory

使用二级缓存需要具备以下几个条件:

  1. <setting name="cacheEnabled" value="true"> 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认就是true,无需设置
  2. 在需要使用二级缓存的SqlMapper.xml文件中添加配置:<cache />
  3. 使用二级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接口
  4. SqlSession对象关闭或提交之后,一级缓存中的数据才会被写入到二级缓存当中。此时二级缓存才可用。

1、CarMapper.xml

<cache/>

2、Car类

public class Car implements Serializable {
//......
}

3、CarMapperTest

@Test
public void testSelectById2() throws Exception{SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);Car car1 = mapper1.selectById(83L);System.out.println(car1);// 关键一步sqlSession1.close();SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);Car car2 = mapper2.selectById(83L);System.out.println(car2);
}

4、查看运行结果

二级缓存的失效:只要两次查询之间出现了增删改操作。二级缓存就会失效。【一级缓存也会失效】

5、二级缓存的相关配置:

①、eviction:指定从缓存中移除某个对象的淘汰算法。默认采用LRU策略。

  • LRU:Least Recently Used。最近最少使用。优先淘汰在间隔时间内使用频率最低的对象。(其实还有一种淘汰算法LFU,最不常用。)
  • FIFO:First In First Out。一种先进先出的数据缓存器。先进入二级缓存的对象最先被淘汰。
  • SOFT:软引用。淘汰软引用指向的对象。具体算法和JVM的垃圾回收算法有关。
  • WEAK:弱引用。淘汰弱引用指向的对象。具体算法和JVM的垃圾回收算法有关。

②、flushInterval:

  • 二级缓存的刷新时间间隔。单位毫秒。如果没有设置。就代表不刷新缓存,只要内存足够大,一直会向二级缓存中缓存数据。除非执行了增删改。

③、readOnly:

  • true:多条相同的sql语句执行之后返回的对象是共享的同一个。性能好。但是多线程并发可能会存在安全问题。
  • false:多条相同的sql语句执行之后返回的对象是副本,调用了clone方法。性能一般。但安全。

④、size:

设置二级缓存中最多可存储的java对象数量。默认值1024。

三、MyBatis集成EhCache

  • 集成EhCache是为了代替mybatis自带的二级缓存。一级缓存是无法替代的。
  • mybatis对外提供了接口,也可以集成第三方的缓存组件。比如EhCache、Memcache等。都可以。
  • EhCache是Java写的。Memcache是C语言写的。所以mybatis集成EhCache较为常见,按照以下步骤操作,就可以完成集成:

第一步:引入mybatis整合ehcache的依赖。(pom.xml)

<!--mybatis集成ehcache的组件-->
<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.2.2</version>
</dependency>

第二步:在类的根路径下新建echcache.xml文件,并提供以下配置信息。(ehcache.xml)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"updateCheck="false"><!--磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存--><diskStore path="e:/ehcache"/><!--defaultCache:默认的管理策略--><!--eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断--><!--maxElementsInMemory:在内存中缓存的element的最大数目--><!--overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上--><!--diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false--><!--timeToIdleSeconds:对象空闲时间(单位:秒),指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问--><!--timeToLiveSeconds:对象存活时间(单位:秒),指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问--><!--memoryStoreEvictionPolicy:缓存的3 种清空策略--><!--FIFO:first in first out (先进先出)--><!--LFU:Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存--><!--LRU:Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存--><defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/></ehcache>

第三步:修改SqlMapper.xml文件中的<cache/>标签,添加type属性。(CarMapper.xml)

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

第四步:编写测试程序使用。(CarMapperTest.testSelectById2)

@Test
public void testSelectById2() throws Exception{SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);Car car1 = mapper1.selectById(83L);System.out.println(car1);sqlSession1.close();SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);Car car2 = mapper2.selectById(83L);System.out.println(car2);
}

第五步:查看运行结果

MyBatis(十四)MyBatis的缓存相关推荐

  1. springboot mybatis ehcache_SpringBoot入门建站全系列(十四)集成Redis缓存

    SpringBoot入门建站全系列(十四)集成Redis缓存 一.概述 本地缓存,就是使用应用内使用本地内存将数据暂缓存储,一般数据库的查询如果不怎么改动,可以用本地缓存暂存. 远程缓存,比如redi ...

  2. 十、MyBatis的缓存

    文章目录 十.MyBatis的缓存 10.1 MyBatis的一级缓存 场景1:判断同一个sqlSession是否查询1级缓存,答案:会查询1级缓存 场景2:判断不同sqlSession是否查询1级缓 ...

  3. mybatis学习教程中级(十)mybatis和ehcache缓存框架整合(重点)

    1.前言 前面讲解了mybatis的一级.二级缓存.一级然并卵(spring整合后),二级还是有用的.我们现在来看看用ehcache来维护管理二级缓存.不要问我为什么,因为都这么用!!!java是框架 ...

  4. 深入浅出 MyBatis 的一级、二级缓存机制

    一.MyBatis 缓存 缓存就是内存中的数据,常常来自对数据库查询结果的保存.使用缓存,我们可以避免频繁与数据库进行交互,从而提高响应速度. MyBatis 也提供了对缓存的支持,分为一级缓存和二级 ...

  5. Mybatis基础学习之一级缓存和二级缓存的简单使用

    前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个Mybatis ...

  6. 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项

    MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上.MyBatis提供了一级缓存.二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高系统的性能.本 ...

  7. spring boot 入门_SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作

    SpringBoot入门建站全系列(三十)Mybatis多数据源进行数据库操作 一.概述 多数据源,就是有多个数据库的配置. 多数据源配置并不麻烦,使用起来和单数据源基本相同,但是,重要的是事务的控制 ...

  8. 《深入理解mybatis原理》 MyBatis缓存机制的设计与实现

    本文主要讲解MyBatis非常棒的缓存机制的设计原理,给读者们介绍一下MyBatis的缓存机制的轮廓,然后会分别针对缓存机制中的方方面面展开讨论. MyBatis将数据缓存设计成两级结构,分为一级缓存 ...

  9. Redis系列(十四)、Redis6新特性之RESP3与客户端缓存(Client side caching)

    Redis6引入新的RESP3协议,并以此为基础加入了客户端缓存的新特性,在此特性下,大大提高了应用程序的响应速度,并降低了数据库的压力,本篇就带大家来看一下Redis6的新特性:客户端缓存. 目录 ...

最新文章

  1. mysql datafiles_mysql datafiles是什么
  2. [P1363] 幻想迷宫
  3. Jupyter notebook 的使用
  4. 使用parted命令对硬盘进行操作
  5. 在 Excel 里使用 ODBC 读取 SAP BTP 平台上 CDS view 的数据
  6. 乔布斯和任正非相比,谁更厉害?
  7. linux重新启动某一个项目,Linux运维知识之supervisor更改某项目配置后 需要重新启动才有效...
  8. java中json数据_java中的JSON对象的使用
  9. 【算法】剑指 Offer 22. 链表中倒数第k个节点
  10. mac下 home-brew安装及php,nginx环境安装及配置
  11. DNS解释问题:java.net.UnknownHostException
  12. java赋值两个对象数组 clone_Java:类的两个相同对象数组的克隆问题
  13. matplotlib中subplot的各参数的作用
  14. 利用接口检查日期是否为法定节假日
  15. ACCESS 中屏蔽shift键
  16. 简单的c语言递归算法题,一天一个算法题-简单的-递归-计算a+aa+aaa+...+aaaa...a的数值...
  17. WeX5制作的app,界面模仿b站(哔哩哔哩弹幕视频网)客户端
  18. 大型复杂项目集管理之二——项目集治理
  19. 主分区与逻辑分区的区别
  20. Python练习猜拳,利用while循环自定义函数,结果数据存入excel表格

热门文章

  1. 小程序开发总结-SPUSKU
  2. 面试时要注意的一些问题
  3. JS函数前加!是什么意思
  4. springboot+mybatis+vue3.0+ts+elementUIplus学生管理系统
  5. 10亿美金的惊天收购!苹果拿下了英特尔手机调制解调器业务
  6. 99公益日“送爷爷奶奶花样出道”直播圆满落幕
  7. kafka 消息格式设计实现
  8. VueJs 打包之后遇到的坑
  9. 基于SSM的手机商城平台的设计与实现(附源码获取链接)
  10. Python对象和类