MyBatis 一级缓存、二级缓存全详解

 

什么是缓存

缓存就是内存中的一个对象,用于对数据库查询结果的保存,用于减少与数据库的交互次数从而降低数据库的压力,进而提高响应速度。

什么是MyBatis中的缓存

MyBatis 中的缓存就是说 MyBatis 在执行一次SQL查询或者SQL更新之后,这条SQL语句并不会消失,而是被MyBatis 缓存起来,当再次执行相同SQL语句的时候,就会直接从缓存中进行提取,而不是再次执行SQL命令。

MyBatis中的缓存分为一级缓存和二级缓存,一级缓存又被称为 SqlSession 级别的缓存,二级缓存又被称为表级缓存。

SqlSession是什么?SqlSession 是SqlSessionFactory会话工厂创建出来的一个会话的对象,这个SqlSession对象用于执行具体的SQL语句并返回给用户请求的结果。

SqlSession级别的缓存是什么意思?SqlSession级别的缓存表示的就是每当执行一条SQL语句后,默认就会把该SQL语句缓存起来,也被称为会话缓存

MyBatis 中的一级缓存

一级缓存是 SqlSession级别 的缓存。在操作数据库时需要构造 sqlSession 对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的 sqlSession 之间的缓存数据区域(HashMap)是互相不影响的。用一张图来表示一下一级缓存,其中每一个 SqlSession 的内部都会有一个一级缓存对象。

数据查找过程:
二级缓存(默认关闭) -> 一级缓存(默认开启) -> 数据库
一级缓存
一级缓存是SqlSession自带的。SqlSession对象被创建,一级缓存就存在了。//是针对每一个sqlSession进行缓存。
如果SqlSession对象关闭或调用清理方法,会导致缓存失效。
缓存底层实现就是通过HashMap实现的。
一级缓存介质——内存
如果 执行sqlsession的DML等操作,会执行commit(提交事务),最终会清空缓存(flush)。sqlSession对象销毁,一级缓存数据不存在了。sqlSession与SqlSession之间的一级缓存互相不影响。

MyBatis 二级缓存:
二级缓存是针对每个mapper相同 的namespace进行缓存。每个SqlSession都会首先调用mapper下的sql语句,每个mapper缓存各自的数据(存储了查询的结果集(java对象))。
每个SqlSession都可以访问到二级缓存中的数据(二级缓存SqlSessionFactory进行管理的),sqlsession对象销毁,mapper中的二级缓存数据仍然存在。

二级缓存介质——内存,硬盘(内存不够走硬盘)
二级缓存SqlSessionFactory(多个SqlSession共享)进行管理的。
.二级缓存的原理:

Mybatis框架提供了Cache接口,缓存组件(比如redis)实现接口。//用redis做mybatis二级缓存:首先开启全局配置开关,然后编写cache的实现类,重写方法,然后在xxxClass的mapper文件里在标签里设置type属性,指定缓存实现类
二级缓存配置:
1.打开总开关: 
在核心配置文件SqlMapConfig.xml中加入

<!--注意顺序-->
<setting name="cacheEnabled" value="true"/>

2.在需要开启二级缓存的mapper.xml中加入caceh标签  

3.二级缓存的POJO类实现Serializable接口

二级缓存失效情况
1.在查询select标签内设置useCache="false",强制关闭二级缓存,如果要使用,得打开

<selectid="getStuById" parameterType="Integer"resultType="Student" useCache="false">

selectstu_id stuId,stu_name stuName from tbl_student where stu_id=#{stuId}

</select>

2.在执行DML操作时刷新缓存

<updateid="updateStu"parameterType="com.atguigu.mybatis.entity.Student" flushCache="true">

updatetbl_student set stu_name=#{stuName} where stu_id=#{stuId}

</update>

这是默认设置(不启动二级缓存),通常不必修改

二级缓存使用场景:
前提:

1.对于查询多,DML少,实时性要求不高(缓存一般都用在这种场景)

2.只有单表操作的表上使用二级缓存,并且所有关于这个表的操作都得在一namespace下   //其他namespace下,包含这个表的操作,那么数据不一致。比如user表,role表,userRole表,不管userRole表的查询放到user的namespace下,还是role的namespace下,user或role的表数据变更后,都会导致userRole的查询有误差

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值