一、缓存概述
1.1 缓存的简介
-
缓存是一个内存中临时存储数据的区域 (cache)
-
用户可以将经常查询的语句放在缓存中,当用户查询数据不用从数据库获取,而是直接从缓存中查询,从而提高查询效率
1.2 缓存的意义
-
避免频繁的对数据库进行访问,当查询次数比较多,缓存命中率比较高的时候,使用缓存对性能的提升十分明显。
1.3 Mybatis的缓存
-
mybatis提供了对于缓存的支持
-
mybatis支持一级缓存和二级缓存,另外还支持自定义缓存
默认情况下,只开启一级缓存(SqlSession级别的缓存,也成为本地缓存)
二级缓存是Mapper级别的(也可以认为是namespace级别的)
二、一级缓存
-
一级缓存也叫做本地缓存。它是基于SqlSession的
-
在数据库的依次会话(一个SqlSession)中,查询到的数据将被放在本地缓存中
-
如果在会话期间,重复查询同一条Sql语句,将直接从缓存中读取(前提是缓存没有失效,后面将会讲解缓存失效的场景)
-
当会话关闭,一级缓存也随之清除
@Test
public void domeTest06(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao mapper = MybatisUtil.getMapper(sqlSession, StudentDao.class);
System.out.println(mapper);
Student s = mapper.findById("001");
System.out.println(s);
Student s2 = mapper.findById("001");
System.out.println(s2);
sqlSession.commit();
sqlSession.close();
}
}
-
注:
-
一级缓存是默认开启的,不需要配置
-
一级缓存的作用域是SqlSesson,SqlSession类的实例对象中有一个HaspMap的数据结构,用于存储缓存数据,不同SqlSession的缓存数据互不影响,每次执行查询语句时,会将查询结构存储在缓存中,当下一次执行相同的Sql语句时,会直接从缓存中得到(如果缓存没有刷新)
-
当SqlSession关闭,一级缓存也随之消失
-
-
一级缓存失效的情况:
-
不在同一个SqlSession中
-
执行语句的参数不同
-
执行增、删、改语句会刷新缓存(包括一二级缓存)
-
手动清空缓存
-
-
注:
当mybatis整合到Spring中时,非事务环境下,每次操作数据库都使用新的sqlSession对象,一级缓存会失效。
三、二级缓存
-
二级缓存也叫全局缓存
-
二级缓存需要我们手动开启
-
对于同一个namespace,它是可以跨SqlSession域的,每一个namespace都有自己的一个二级缓存区域
-
二级缓存的工作过程:
-
一个SqlSession会话查询一条数据,该条数据的缓存就被放在当前的会话的一级缓存中
-
当前会话关闭,一级缓存的数据会被写入二级缓存,一级缓存被清除
-
当有新建会话时,会优先从二级缓存中获取数据
-
在没有开启二级缓存时:
@Test
public void domeTest07(){
SqlSession sqlSession1 = MybatisUtil.getSqlSession();
StudentDao mapper1 = MybatisUtil.getMapper(sqlSession1, StudentDao.class);
Student s1 = mapper1.findById("001");
System.out.println(s1);
sqlSession1.commit();
sqlSession1.close();
SqlSession sqlSession2 = MybatisUtil.getSqlSession();
StudentDao mapper2 = MybatisUtil.getMapper(sqlSession2, StudentDao.class);
Student s2 = mapper2.findById("001");
System.out.println(s2);
sqlSession2.commit();
sqlSession2.close();
}
二级缓存使用需要开启:
在mybatis核心配置文件中开启缓存(默认是开启的)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
在映射配置文件中开启二级缓存(只对当前配置映射生效),其中的参数是可以省略的(使用默认配置)
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
配置详解:
1、eviction:清除策略,默认为LRU
LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
2、flushInterval(刷新间隔)属性可以被设置为任意的正整数
3、size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。
4、readOnly(只读)属性可以被设置为 true 或 false。默认为false,
注:若此处设置未false,则对应的实体类必须进行序列化,否则会报错。
详情参考mybatis官网:https://mybatis.net.cn/sqlmap-xml.html#cache