Mybatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。
Mybatis 系统中默认定义了两级缓存:一级缓存和二级缓存
- 默认情况下,只有一级缓存(
SqlSession 级别的缓存、也称作本地缓存) - 二级缓存需要手动开启和配置,它是基于
namespace 级别的缓存
一级缓存(本地缓存)
一级缓存作用域默认为SqlSession 。同一次会话期间只要查询过的数据都会保存在当前SqlSession 的一个Map 中。当 Session flush 或 close 后, 该Session 中的所有 Cache 将被清空。 一级缓存不能被关闭, 但可以调用 clearCache() 来清空本地缓存, 或者改变缓存的作用域。
(1)修改缓存作用域
可以在全局配置文件修改一级缓存的缓存作用域 mybatis-config.xml
<settings>
<setting name="localCacheScope" value="STATEMENT"/>
</settiongs>
(2)失效的情况
- 不同的
SqlSession 对应不同的一级缓存 如下面的变量 sqlSession 和 sqlSession 1
@Test
public void test() {
SqlSession sqlSession = MyTest.getSqlSessionFactory().openSession();
SqlSession sqlSession1 = MyTest.getSqlSessionFactory().openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
EmployeeMapper mapper1 = sqlSession1.getMapper(EmployeeMapper.class);
System.out.println(mapper.getEmployeeByDid(2));
sqlSession.close();
System.out.println(mapper1.getEmployeeByDid(2));
sqlSession1.close();
}
- 同一个
SqlSession 但是查询条件不同 如下面调用getEmployeeByDid 的输入参数不同
@Test
public void test() {
SqlSession sqlSession = MyTest.getSqlSessionFactory().openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
System.out.println(mapper.getEmployeeByDid(1));
System.out.println(mapper.getEmployeeByDid(2));
sqlSession.close();
}
- 同一个
SqlSession 两次查询期间执行了任何一次增删改操作 如下面在两次查询方法间执行了删除方法deleteEmployee
@Test
public void test() {
SqlSession sqlSession = MyTest.getSqlSessionFactory().openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
System.out.println(mapper.getEmployeeByDid(1));
mapper.deleteEmployee(3);
System.out.println(mapper.getEmployeeByDid(2));
sqlSession.close();
}
- 同一个
SqlSession 两次查询期间手动清空了缓存 如下面调用了clearCache() 方法清空缓存
@Test
public void test() {
SqlSession sqlSession = MyTest.getSqlSessionFactory().openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
System.out.println(mapper.getEmployeeByDid(1));
sqlSession.clearCache();
System.out.println(mapper.getEmployeeByDid(2));
sqlSession.close();
}
二级缓存
二级缓存全局作用域缓存。
- 二级缓存默认不开启,需要手动配置
MyBatis 提供二级缓存的接口以及实现,缓存实现要求 POJO 实现Serializable 接口- 二级缓存在
SqlSession 关闭或提交之后才会生效
(1)步骤
- 全局配置文件中开启二级缓存
<settiengs>
<setting name="cacheEnabled" value="true"/>
</settings>
- 需要使用二级缓存的映射文件处使用
cache 配置缓存
<cache/>
- POJO 需要实现
Serializable 接口
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String lastName;
private String email;
private String gender;
}
(2)cache相关属性
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>
eviction :缓存回收策略:
LRU – 最近最少使用的:移除最长时间不被使用的对象。FIFO – 先进先出:按对象进入缓存的顺序来移除它们。SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。- 默认的是
LRU 。 flushInterval :刷新间隔,单位毫秒 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新size :引用数目,正整数,默认值是 1024。 代表缓存最多可以存储多少个对象,太大容易导致内存溢出readOnly :只读,属性可以被设置为 true 或 false,默认是 false。
- true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象
不能被修改。这提供了很重要的性能优势。 - false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,
但是安全。
缓存相关设置
除了上面提到的setting 的子元素cacheEnable 和sqlSession 的方法flushCache() ,还有:
select 标签的useCache 属性: 配置这个select 是否使用二级缓存。一级缓存一直是使用的<select id="getEmployee" resultType="employee" useCache="true">
select * from employee where id = #{id}
</select>
- sql 标签的
flushCache 属性: 增删改默认flushCache=true 。sql 执行以后,会同时清空一级和二级缓存。 查询默认flushCache=false <select id="getEmployee" resultType="employee" flushCache="true">
select * from employee where id = #{id}
</select>
第三方缓存整合
E
h
C
a
c
h
e
EhCache
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是
H
i
b
e
r
n
a
t
e
Hibernate
Hibernate 中默认的CacheProvider 。
步骤
- 导入echcahe需要的包,以及整合包、日志包。
pom.xml
<dependencies>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.0-alpha5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0-alpha5</version>
</dependency>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
- 编写 ehcache.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="E:\ehcache" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
- 配置 cache 标签
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
参考缓存:若想在命名空间中共享相同的缓存配置和实例。可以使用 cache-ref 元素来引用另外一个缓存。
<cache-ref namespace="com.atguigu.mybatis.dao.EmployeeMapper"/>
|