mybatis 一级,二级缓存原理

 

 

二、MyBatis 的主要层次结构
使用 MyBatis 对数据库操作的代码,能够看见的就是这个 SqlSession 对象。实际上,这只是 MyBatis 对外暴露的接口,整个 MyBatis 核心部件是下面的这么一堆接口和类:

1️⃣SqlSession:MyBatis 工作的主要顶层 API,表示和数据库交互的会话,完成必要数据库增删改查功能。
2️⃣Executor:MyBatis 执行器,整个 MyBatis 调度的核心,负责 SQL 语句的生成和查询缓存的维护。
3️⃣StatementHandler:封装了 JDBC Statement 操作,负责对 JDBC statement 的操作,如设置参数、将 Statement 结果集转换成 List 集合。
4️⃣ParameterHandler:负责对用户传递的参数转换成 JDBC Statement 所需要的参数。
5️⃣ResultSetHandler:负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。
6️⃣TypeHandler:负责 Java 数据类型和 jdbc 数据类型之间的映射和转换。
7️⃣MappedStatement:MappedStatement 维护了一条节点的封装。
8️⃣SqlSource:负责根据用户传递的 parameterObject,动态地生成 SQL 语句,将信息封装到 BoundSql 对象中,并返回。
9️⃣BoundSql:表示动态生成的 SQL 语句以及相应的参数信息。
🔟Configuration:MyBatis 所有的配置信息都维持在 Configuration 对象之中。

上面这堆接口和类的层次关系如图:

 

总结:

MyBatis 封装了 JDBC 操作,对外暴露了 SqlSession 接口进行数据库的操作。但是实际 MyBatis 最核心的接口是 Executor,它负责 SQL 语句的生成和查询缓存的维护。如果没有缓存就查数据库,有缓存就使用的是 PerpetualCache 中的 HashMap 保存的数据缓存。MyBatis 的一级缓存其实就保存在一个 HashMap 中。HashMap 如何判断查询方法是否相同?其实主要是通过 HashMap 的 key 值。
 

三、MyBatis 的一级缓存
1️⃣一级缓存最简单的组织形式

MyBatis 在一次会话的表示——一个 SqlSession 对象中创建一个本地缓存(local cache),对于每一次查询,都会尝试根据查询的条件去本地缓存中查找是否在缓存中,如果在,就直接从缓存中取出,然后返回给用户;否则,从数据库读取数据,将查询结果存入缓存并返回给用户。


类似于最开始保存的方式,只是从一个简单的对象,换成了封装好了的更加复杂的 Local Cache 对象。

 

 

实际上,SqlSession 只是一个 MyBatis 对外的接口,SqlSession 将它的工作交给了 Executor 执行器这个角色来完成,负责完成对数据库的各种操作。当创建了一个 SqlSession 对象时,MyBatis 会为这个 SqlSession 对象创建一个新的 Executor 执行器,而缓存信息就被维护在这个 Executor 执行器中,MyBatis 将缓存和对缓存相关的操作封装在 Cache 接口中。它们之间的组织关系,大概如下图:


2️⃣一级缓存的生命周期


MyBatis 在开启一个数据库会话时,会创建一个新的 SqlSession 对象,SqlSession 对象中会有一个新的 Executor 对象,Executor 对象中持有一个新的 PerpetualCache 对象(Cache 接口的实现类);当会话结束时,SqlSession 对象及其内部的 Executor 对象还有 PerpetualCache 对象也一并释放掉。
如果 SqlSession 调用了 close(),会释放掉一级缓存 PerpetualCache 对象,一级缓存将不可用。
如果 SqlSession 调用了 clearCache(),会清空 PerpetualCache 对象中的数据,但是 SqlSession 对象仍可使用。
SqlSession 中执行任何一个增/删/改操作之后执行事务提交 commit() ,都会清空PerpetualCache 对象的数据,但是 SqlSession 对象可以继续使用。

 四、MyBatis 的二级缓存

 

1️⃣二级缓存使用场景

类似于统计排行榜的查询,可能会涉及到多张表很多字段的查询统计排序,是非常费时费力的。如果每次都去数据库查询显示一次排行榜数据,那到排行榜这里,必定会卡顿很久,而且这种卡顿是用户不能忍受的。做成一级缓存也是不可行的,每次 SqlSession 请求,每个客户上来难道都要卡顿一次吗?所以,这种查询肯定要做成全局的缓存,当应用启动的时候就缓存这种查询数据,然后每一周刷新一次这种数据就可以了。

由此,简单总结二级缓存的特点和使用场景:二级缓存作用于全局,对于一些相当消耗性能的,并且对于时效性不敏感的查询可以使用二级缓存。注意,如果开启了二级缓存,查询的顺序是二级缓存 → 一级缓存 → 数据库。
————————————————
版权声明:本文为CSDN博主「Just-ForStudy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ChineseSoftware/article/details/122881217

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值