十三、MyBatis的缓存
缓存:cache
缓存的作用:通过减少IO的方式,来提高程序的执行效率。
mybatis的缓存:将select语句的查询结果放到缓存(内存)当中,下一次还是这条select语句的话,直接从缓存中取,不再查数据库。一方面是减少了IO。另一方面不再执行繁琐的查找算法。效率大大提升。
mybatis缓存包括:
- 一级缓存:将查询到的数据存储到SqlSession中。
- 二级缓存:将查询到的数据存储到SqlSessionFactory中。
- 或者集成其它第三方的缓存:比如EhCache【Java语言开发的】、Memcache【C语言开发的】等。
缓存只针对于DQL语句,也就是说缓存机制只对应select语句。
1.一级缓存
一级缓存默认是开启的。不需要做任何配置。
原理:只要使用同一个SqlSession对象执行同一条SQL语句,就会走缓存。
<select id="selectById" resultType="Car">select * from t_car where id = #{id}</select>
@Test
public void testSelectById(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper1 = sqlSession.getMapper(CarMapper.class);Car car1 = mapper1.selectById(25L);System.out.println(car1);CarMapper mapper2 = sqlSession.getMapper(CarMapper.class);Car car2 = mapper2.selectById(25L);System.out.println(car2);sqlSession.close();
}
Preparing: select * from t_car where id = ?
Parameters: 25(Long)
Total: 1
Car{id=25, carNum='2222', brand='丰田霸道', guidePrice=11.0, produceTime='2020-11-11', carType='燃油车'}
Car{id=25, carNum='2222', brand='丰田霸道', guidePrice=11.0, produceTime='2020-11-11', carType='燃油车'}
只执行了一次sql语句,因为两句sql一样所以直接从缓存中拿
什么情况下不走缓存?
- 第一种:SqlSession对象不是同一个,肯定不走缓存
- 第二种:查询条件不一样,肯定也不走缓存
什么情况下一级缓存失效
- 第一次DQL和第二次DQL之间做了以下两件事中的任意一件,都会让一级缓存清空
- 执行了sqlSession的clearCache()方法,这是手动清空一级缓存。
sqlSession.clearCache();
- 执行了sqlSession的clearCache()方法,这是手动清空一级缓存。
- 执行了INSERT或DELETE或UPDATE语句。不管你是操作哪张表的,都会清空一级缓存。
2. 二级缓存
二级缓存的范围是SqlSessionFactory。
使用二级缓存需要具备以下几个条件:
- <setting name=“cacheEnabled” value=“true”> 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认就是true,无需设置。
- 在需要使用二级缓存的SqlMapper.xml文件中添加配置:<cache />
<mapper namespace="com.powernode.mybatis.mapper.CarMapper"><!--默认情况下,二级缓存机制是开启的。只需要在对应的SqlMapper.xml文件中添加以下标签。用来表示使用该二级缓存。--><cache/><select id="selectById" resultType="Car">select * from t_car where id = #{id}</select> </mapper>
- 使用二级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接口
package com.powernode.mybatis.pojo; import java.io.Serializable; public class Car implements Serializable {private Long id;private String carNum;private String brand;private Double guidePrice;private String produceTime;private String carType;......//此处省略构造方法、getting setting toString方法
- SqlSession对象关闭或提交之后,一级缓存中的数据才会被写入到二级缓存当中。此时二级缓存才可用。
@Test public void testSelectById() throws Exception{// 这里只有一个SqlSessionFactory对象。二级缓存对应的就是SqlSessionFactory。SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);// 这行代码执行结束之后,实际上数据是缓存到一级缓存当中了。(sqlSession1是一级缓存。)Car car1 = mapper1.selectById(164L);System.out.println(car1);// 如果这里不关闭SqlSession1对象的话,二级缓存中还是没有数据的。// 执行了这行代码,sqlSession1的一级缓存中的数据会放到二级缓存当中。sqlSession1.close();// 这行代码执行结束之后,实际上数据会缓存到一级缓存当中。(sqlSession2是一级缓存。)Car car2 = mapper2.selectById(164L);System.out.println(car2);// 程序执行到这里的时候,会将sqlSession2这个一级缓存中的数据写入到二级缓存当中。sqlSession2.close(); }
二级缓存的失效:只要两次查询之间出现了增删改操作。二级缓存就会失效。【一级缓存也会失效】
二级缓存的相关配置:cache标签的属性
- eviction:指定从缓存中移除某个对象的淘汰算法。默认采用LRU策略。
LRU:Least Recently Used。最近最少使用。优先淘汰在间隔时间内使用频率最低的对象。
FIFO:First In First Out。一种先进先出的数据缓存器。先进入二级缓存的对象最先被淘汰。
SOFT:软引用。淘汰软引用指向的对象。具体算法和JVM的垃圾回收算法有关。
WEAK:弱引用。淘汰弱引用指向的对象。具体算法和JVM的垃圾回收算法有关。 - flushInterval:
二级缓存的刷新时间间隔。单位毫秒。如果没有设置。就代表不刷新缓存,只要内存足够大,一直会向二级缓存中缓存数据。除非执行了增删改。 - readOnly:
true:多条相同的sql语句执行之后返回的对象是共享的同一个。性能好。但是多线程并发可能会存在安全问题。
false:多条相同的sql语句执行之后返回的对象是副本,调用了clone方法。性能一般。但安全。 - size:
设置二级缓存中最多可存储的java对象数量。默认值1024
3.MyBatis集成EhCache
集成EhCache是为了代替mybatis自带的二级缓存。一级缓存是无法替代的。
mybatis对外提供了接口,也可以集成第三方的缓存组件。比如EhCache、Memcache等。都可以。
EhCache是Java写的。Memcache是C语言写的。所以mybatis集成EhCache较为常见
按照以下步骤操作,就可以完成集成:
第一步:pom.xml引入mybatis整合ehcache的依赖。
<!--mybatis集成ehcache的组件-->
<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.2.2</version>
</dependency>
第二步:在类的根路径下新建echcache.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文件中的标签,添加type属性。
<!--集成Ehcache组件-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
十三、MyBatis的缓存相关推荐
- mybatis查询缓存——(十三)
1. mybatis缓存介绍 如下图,是mybatis一级缓存和二级缓存的区别图解: mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. ...
- (十二)Mybatis的缓存机制
文章目录 环境 Mybatis的缓存 一级缓存 一级缓存失效 方式一 方式二 二级缓存 MyBatis集成EhCache缓存 Mybatis学习目录 上一篇:(十一)MyBatis的高级映射及延迟加载 ...
- 深入了解MyBatis二级缓存
深入了解MyBatis二级缓存 一.创建Cache的完整过程 我们从SqlSessionFactoryBuilder解析mybatis-config.xml配置文件开始: Reader reader ...
- springboot mybatis 事务_SpringBoot 下 Mybatis 的缓存
"IT魔幻屋"致力于让你遇见更好的自己! 说起 mybatis,作为 Java 程序员应该是无人不知,它是常用的数据库访问框架.与 Spring 和 Struts 组成了 Java ...
- 通过源码分析MyBatis的缓存
前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...
- Mybatis二级缓存原理
记录是一种精神,是加深理解最好的方式之一. 最近看了下Mybatis的源码,分析了二级缓存的实现方式,在这里把他记下来.虽然这不复杂,对这方面的博客也有很多,写的也很好.但我坚信看懂了是其一,能够教别 ...
- mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache
1 查询缓存 1.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在 ...
- Mybatis一级缓存,二级缓存的实现就是这么简单
介绍 又到了一年面试季,所以打算写一点面试常问的东西,争取说的通俗易懂.面试高级岗,如果你说熟悉Mybatis,下面这些问题基本上都会问 Mybatis插件的实现原理? 如何写一个分页插件? Myba ...
- (转)mybatis一级缓存二级缓存
一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...
最新文章
- HBASE+Solr实现详单查询--转
- 输入 n 个整数,输出其中最小的 k 个
- luogu4389 付公主的背包
- SpringMvc 注解 @InitBinder 表单多对象精准绑定接收
- 机器学习算法(8)——朴素贝叶斯、最小风险贝叶斯决策
- 为Visual Studio更换皮肤和背景图
- 配置文件中有“路径信息”时,需呀注意的问题(路径中的\是转义字符)~
- bnx2: Can't load firmware file bnx2/bnx2-mips-09-6.2.1b.fw
- ffmpeg (四):ffmpeg, ffplay, ffprobe用法
- 2060显卡驱动最新版本_我们平时电脑的驱动需要一直更新吗?教你如何正确的维护你的驱动...
- Java找不到对象的警告_程序猿的24个段子:程序员找不到对象 一般有三种情况...
- 51单片机系列--蜂鸣器
- 下载安装最新kali虚拟机及切换中文方法
- 深入理解SR-IOV和IO虚拟化
- python文件读写操作
- 神经网络自我认知模型
- 数据规范化与数据离散化
- 2021年三季度中国调味发酵品行业A股上市企业营收排行榜:上市企业归属母公司净利润均处于盈利状态(附热榜TOP14详单)
- k线分析中的量化测试方法_k线分析中如何使用量化思维案例分析
- AnnotationAttributes
热门文章
- 常用字体颜色(中英文名对照)
- m基于机器学习MLP的OFDM信道估计误码率matlab仿真,对比LS和MMSE两种信道估计算法
- JAVA——界面设计Swing教程
- 如何更好地使用loading
- 最小C语言编译器TCC的使用
- MOOC 北京大学 《人工智能实践》 课程笔记(文末有全部代码)
- C语言:学生信息管理系统
- vscode代码一保存就缩进四个空格,解决vscode缩进四个空格问题
- java计算机毕业设计手机电子商城源码+系统+数据库+lw文档+mybatis+运行部署
- 天地人大湖北版2004-2005学年度第二学期第一次版聚总结