0%

MyBatis缓存

MyBatis缓存

1 一级缓存(本地缓存)

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中,以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
  • 一级缓存是sqlSession级别的缓存,是一直开启的

1.1 一级缓存失效的四种情况

  • sqlSession不同:一级缓存是sqlSession级别的缓存,所以如果重新开一个sqlSession,并不会共享其他sqlSession的缓存,仍然需要发送请求到数据库进行查询
  • sqlSession相同,查询条件不同:这种情况很好理解,因为之前没有查询过,所以在一级缓存中没有对应的数据
  • sqlSession相同,两次查询间执行了增删改操作:MyBatis执行增删改操作会清空缓存
  • sqlSession相同,手动清空了一级缓存:调用SqlSession对象的clearCache方法清空一级缓存

2 二级缓存(全局缓存)

img

  • 二级缓存是namespace级别的缓存

2.1 工作机制

  • 一个session过程中查询的数据会被放在当前session的一级缓存中
  • 如果session关闭,一级缓存中的数据就被保存到二级缓存中,从而新的session查询就可以参照二级缓存
  • 不同namespace查出的数据会被放在自己对应的缓存中

2.2 使用

  • 开启全局二级缓存配置,
1
<setting name="cacheEnabled" value="true"/>
  • 在Mapper xml文件配置使用二级缓存,
1
2
3
4
<mapper namespace="com.lnhoo.mapper.EmployeeMapper">
<cache eviction="LRU" readOnly="true" size="65536"></cache>
......
</mapper>
  • 实现POJO的序列化接口

2.3 cache标签参数

参数 功能
eviction 缓存的回收策略, LRU:最近最少使用的,移除最长时间不被使用的对象 FIFO:先进先出,按对象进入缓存的顺序移除 SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象 WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则地对象
flushInterval 缓存刷新间隔,即每隔多少毫秒清空缓存,默认不清空
readOnly 是否只读, 只读:MyBatis认为所有访问缓存的操作都是只读操作,不会修改数据;为了加快获取速度,直接将数据在缓存中的引用返回给用户;不安全,但是速度快 读写,MyBatis认为获取的数据可能会被修改,会利用序列化、反序列化技术克隆一份新的数据;安全,但是速度慢
size 缓存的元素个数
type 自定义的缓存实现类(通过实现MyBatis Cache接口)

2.4 和缓存有关的设置、属性

  • 1)cacheEnabled:决定二级缓存是否启用
  • 2)useCache:每个select标签都有一个“useCache”属性,决定是否缓存当前sql查询到的数据,默认为true;useCache决定的是二级缓存,对一级缓存无影响
  • 3)flushCache:每个增删改标签都有一个“flushCache”属性,决定是否在sql执行后清空一级、二级缓存
  • 4)sqlSession.clearCache():只清除当前session的一级缓存
  • 5)localCacheScope:本地缓存作用域,默认值为“SESSION”,可选值为“STATEMENT”

3 MyBatis整合ehcache

img

3.1 导入适配器包

1
2
3
4
5
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.2</version>
</dependency>

3.2 导入第三方缓存包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.8.0-beta4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.8.0-beta4</version>
<scope>test</scope>
</dependency>

3.2 Mapper xml配置使用自定义缓存

1
2
3
4
<mapper namespace="com.lnhoo.mapper.EmployeeMapper">
<cache eviction="LRU" readOnly="true" type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
............
</mapper>
  • 可以通过cache标签的type属性指定自定义的缓存实现类

3.3 引用cache配置

  • 有时候希望能够重用其他namespace的cache配置,可以使用cache-ref标签,
1
<cache-ref namespace="com.lnhoo.mapper.EmployeeMapper"/>