mybatis 二级缓存失效_MyBatis 二级缓存全详解

本文详细介绍了MyBatis的二级缓存,包括二级缓存的作用、开启条件、工作流程、配置选项及失效条件。通过示例展示了如何配置和使用二级缓存,并探讨了多表操作对二级缓存的影响以及解决办法。最后,分析了二级缓存的源码,讨论了是否应该使用二级缓存及其注意事项。
摘要由CSDN通过智能技术生成

我们在上一篇文章 ( https://mp.weixin.qq.com/s/4Puee_pPCNArkgnFaYlIjg ) 介绍了 MyBatis 的一级缓存的作用,如何开启,一级缓存的本质是什么,一级缓存失效的原因是什么? MyBatis 只有一级缓存吗?来找找答案吧!

MyBatis 二级缓存介绍

上一篇文章中我们介绍到了 MyBatis 一级缓存其实就是 SqlSession 级别的缓存,什么是 SqlSession 级别的缓存呢?一级缓存的本质是什么呢? 以及一级缓存失效的原因?我希望你在看下文之前能够回想起来这些内容。

MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存,开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示

3a91fe40fbc39db7f2f8ff4c558cc9d2.png

当二级缓存开启后,同一个命名空间(namespace) 所有的操作语句,都影响着一个共同的 cache,也就是二级缓存被多个 SqlSession 共享,是一个全局的变量。当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

二级缓存开启条件

二级缓存默认是不开启的,需要手动开启二级缓存,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。开启二级缓存的条件也是比较简单,通过直接在 MyBatis 配置文件中通过

来开启二级缓存,还需要在 Mapper 的xml 配置文件中加入 标签

设置 cache 标签的属性

cache 标签有多个属性,一起来看一些这些属性分别代表什么意义

eviction: 缓存回收策略,有这几种回收策略

LRU - 最近最少回收,移除最长时间不被使用的对象

FIFO - 先进先出,按照缓存进入的顺序来移除它们

SOFT - 软引用,移除基于垃圾回收器状态和软引用规则的对象

WEAK - 弱引用,更积极的移除基于垃圾收集器和弱引用规则的对象

默认是 LRU 最近最少回收策略

flushinterval 缓存刷新间隔,缓存多长时间刷新一次,默认不清空,设置一个毫秒值

readOnly: 是否只读;true 只读,MyBatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。MyBatis 为了加快获取数据,直接就会将数据在缓存中的引用交给用户。不安全,速度快。读写(默认):MyBatis 觉得数据可能会被修改

size : 缓存存放多少个元素

type: 指定自定义缓存的全类名(实现Cache 接口即可)

blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

探究二级缓存

我们继续以 MyBatis 一级缓存文章中的例子为基础,搭建一个满足二级缓存的例子,来对二级缓存进行探究,例子如下(对 一级缓存的例子部分源码进行修改):

Dept.java

//存放在共享缓存中数据进行序列化操作和反序列化操作

//因此数据对应实体类必须实现【序列化接口】

public class Dept implements Serializable {

private Integer deptNo;

private String dname;

private String loc;

public Dept() {}

public Dept(Integer deptNo, String dname, String loc) {

this.deptNo = deptNo;

this.dname = dname;

this.loc = loc;

}

get and set...

@Override

public String toString() {

return "Dept{" +

"deptNo=" + deptNo +

", dname='" + dname + '\'' +

", loc='" + loc + '\'' +

'}';

}

}

myBatis-config.xml

在myBatis-config 中添加开启二级缓存的条件

DeptDao.xml

还需要在 Mapper 对应的xml中添加 cache 标签,表示对哪个mapper 开启缓存

对应的二级缓存测试类如下:

public class MyBatisSecondCacheTest {

private SqlSession sqlSession;

SqlSessionFactory factory;

@Before

public void start() throws IOException {

InputStream is = Resources.getResourceAsStream("myBatis-config.xml");

SqlSessionFactoryBuilder builderObj = new SqlSessionFactoryBuilder();

factory = builderObj.build(is);

sqlSession = factory.openSession();

}

@After

public void destory(){

if(sqlSession!=null){

sqlSession.close();

}

}

@Test

public void testSecondCache(){

//会话过程中第一次发送请求,从数据库中得到结果

//得到结果之后,mybatis自动将这个查询结果放入到当前用户的一级缓存

DeptDao dao = sqlSession.getMapper(DeptDao.class);

Dept dept = dao.findByDeptNo(1);

System.out.println("第一次查询得到部门对象 = "+dept);

//触发MyBatis框架从当前一级缓存中将Dept对象保存到二级缓存

sqlSession.commit();

// 改成 sqlSession.close(); 效果相同

SqlSession session2 = factory.openSession();</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值