一:缓存 简介
1、什么是缓存 【 Cache 】
- 存在内存中的临时数据
- 将用户经常查询的数据放在缓存 ( 内存 ) 中,用户去查询数据时就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题
2、为什么使用缓存
减少和数据库的交互次数,减少系统开销,提高系统效率
3、什么样的数据 适合 使用缓存呢
经常查询并且不经常改变的数据
二:MyBatis缓存
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存,缓存可以极大的提升查询效率。
MyBatis系统中默认定义了两种缓存:一级缓存 和 二级缓存
- 默认情况下,只有一级缓存开启。( SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,它是基于namespace级别的缓存
- 为了提高扩展性,MyBatis定义了缓存接口 Cache 。我们可以通过实现 Cache 接口来自定义二级缓存
三:MyBatis一级缓存
一级缓存也叫本地缓存
- 与数据库同一次会话期间查询到的数据会放在本地缓存中
- 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
例如
@Test
public void testFindById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.findById(1);
System.out.println(user1);
System.out.println("*******************华丽分割线*******************");
User user2 = mapper.findById(1);
System.out.println(user2);
sqlSession.close();
}
一级缓存总结:
一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接 至 关闭连接这个区间
四:MyBatis二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
二级缓存是基于namespace的缓存,一个名称空间,对应一个二级缓存
工作机制:
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中
- 如果当前会话关闭了,这个会话对应的一级缓存就没了,虽然会话关闭了,但是一级缓存中的数据会被保存到二级缓存中
- 新的会话查询信息,就可以直接从二级缓存中获取内容
- 不同的mapper查到的数据会放在自己对应的缓存( map ) 中。
使用步骤:
1、在核心配置文件中 显式的开启全局缓存
<settings>
<!--显式的开启全局缓存-->
<setting name="cacheEnable" value="true"/>
</settings>
2、在要使用二级缓存的Mapper.xml中开启二级缓存
<!--开启二级缓存-->
<cache/>
3、测试
@Test
public void testFindById2(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.findById(2);
System.out.println(user1);
sqlSession.close();
System.out.println("*******************华丽分割线 下面使用了二级缓存中的数据*******************");
SqlSession sqlSession2 = MyBatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.findById(2);
System.out.println(user2);
sqlSession2.close();
}
4、结果
二级缓存总结:
- 只要开启了二级缓存,在同一个Mapper下就有效
- 所有的数据都会先放在一级缓存中
- 只有当会话提交,或者关闭的时候,才会提交至二级缓存中
五:缓存原理
六:自定义缓存
Ehcache是一种广泛使用的开源Java分布式缓存,主要面向通用缓存。
使用步骤
1、导入坐标依赖
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>
2、在mapper.xml 中指定使用我们的 ehcache 缓存实现
<!--使用自定义缓存(二级缓存)-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
3、在resources中新建 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">
<!--
diskStore:缓存路径 ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置
user.home —— 用户主目录
user.dir —— 用户当前工作目录
java.io.tmpdir —— 默认临时文件路径
-->
<diskStore path="./tmpdir/Tmp_EhCache"/>
<!--
defaultCache: 默认缓存策略,当ehcache 找不到定义的缓存时,则使用这个缓存策略,只能定义一个
-->
<defaultCache
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="cloud_user"
eternal="false"
maxElementsInMemory="5000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
问题:
The setting cacheEnable is not known. Make sure you spelled it correctly (case sensitive).
解决办法:
在mybatis核心配置文件中 去掉 全局缓存开关
注意不是置为false 而是直接注释掉 或 删掉