Mybatis缓存机制(一级缓存、二级缓存、三级缓存)

一、含义:

缓存就是内存中的数据,常常来自对数据库查询结果的保存。
使用缓存,我们可以避免频繁与数据库进行交互,从而提高响应速度。

Mybatis的缓存分为一级缓存、二级缓存、三级缓存。

一级缓存:
作用域是同一个 SqlSession,在同一个 sqlSession 中两次执行相同的 sql 语句,
第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取,从而提高查询效率。当一个 sqlSession 结束后该 sqlSession 中的 一级缓存也就不存在了。Mybatis 默认开启一级缓存。
一级缓存内部存储使用一个 HashMap,key 为 hashCode+sqlId+Sql 语句。value 为 从查询出来映射生成的 java 对象 sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区域。

二级缓存:
是多个 SqlSession 共享的,其作用域是 mapper 的同一个 namespace,不同 的 sqlSession 两次执行相同 namespace 下的 sql 语句且向 sql 中传递参数也相同即最终执行 相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从 缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis 默认没有开启二级缓存 需要在 setting 全局参数中配置开启二级缓存。
开启二级缓存:
1.在yml中添加以下代码
在这里插入图片描述
2.然后在对应的mapper.xml里面加入配置
在这里插入图片描述
在这里插入图片描述注意:开启二级缓存后,对应的pojo一定要实现Serializable,否则在序列化的时候会报错
readOnly:是否只读 。 值为true时,mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。mybatis为了加快获取速度,直接会将数据在缓存中的引用交给用户,不安全,但速度快。
值为false时,mybatis觉得获取的数据可能会被修改,mybatis会利用序列化&反序列化的技术克隆一份新的数据给你,安全,但速度慢。

三级缓存:
Mybatis 的一级缓存与二级缓存 只适用于单体项目,在分布式服务或者微服务架构下 都会出现数据不一致问题。所以Mybatis 为我们提供了自定义缓存 我们可以集成很多三方中间件来做缓存 这里就那Redis来说一下。
在这里插入图片描述

二、区别

1.一级缓存的作用域是一个sqlsession内;二级缓存作用域是针对mapper进行缓存;
2.一级缓存是默认开启的;二级缓存需要手动配置
3.Mybatis 的一级缓存与二级缓存 只适用于单体项目,在分布式服务或者微服务架构下 都会出现数据不一致问题。三级缓存就是为了解决这个问题

三、小结

1.一级缓存的作用域是一个sqlsession内;二级缓存作用域是针对mapper进行缓存;
2.一级缓存是默认开启的;二级缓存需要手动配置
3.一级缓存sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区域。sqlSession.close()后一级缓存也没有了。但是销毁sqlSession后会将里面的缓存存到二级缓存中;
4.二级缓存cache中readonly属性如果为false 那么相应的pojo类必须实现Serializable接口 并且其缓存查询到的对象都是通过序列化或者反序列化克隆的,所以对象之间两两不相等
5.二级缓存的生命周期和应用同步,它是用来解决一级缓存不能跨会话共享数据的问题,范围是namespace级别的,可以被多个会话共享(只要是同一个接口的相同方法,都可以进行共享)。
6.只要没有显式地设置cacheEnabled为false,都会使用CachingExector装饰基本的执行器(SIMPLE、REUSE、BATCH)。 二级缓存总是默认开启的,但是每个Mapper的二级开关是默认关闭的。
7.二级缓存进行增删改操作也会刷新二级缓存,导致二级缓存失效

附,二级缓存的执行流程:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45161172/article/details/129526131