MyBatis 缓存结构

0x00:什么是缓存

在网站的各种业务中,几乎离不开对数据库的增删改查操作,当一个功能点经常需要从数据库读取数据时,访问量大的网站,对数据库会造成很大的压力,这时候,为了缓解数据库的压力,提高运行速度,则缓存就是其中的一个解决办法。

缓存就是第一次用户发来的请求时,将请求的结果放到缓存中,之后其他用户发来同一个请求时,就会直接从缓存中读取第一次保存的数据,减小数据库压力的同时也提高了查询速度。

0x01:MyBatis 中的缓存

MyBatis 中的缓存有两种,一种是一级缓存,另外一种是二级缓存。

一级缓存其实就是 SqlSession 级别的缓存,在操作数据库的时候,每个 SqlSession 类的实例对象中都有一个数据结构 HashMap 可以用于存储缓存数据。不同的 SqlSession 类的实例对象缓存的数据区域 HashMap 是互不影响的。

二级缓存就是 Mapper 级别的缓存,多个 SqlSession 类的实例对象操作同一个 Mapper 配置文件中的 sql 句,多个 SqlSession 类的实例对象可以共用二级缓存,二级缓存是跨 SqlSession 的。

0x02:MyBatis 缓存模式

请输入图片描述

从以上图可以看出来,每个 SqlSession 类的实例对象自身有一个一级缓存,而查询同一个 Mapper 映射文件的 SqlSession 类的实例对象之间又共享同一个二级缓存。

0x03:MyBatis 一级缓存

一级缓存是存在于每一个 SqlSession 的实例对象中的,当我们第一次去查询某一个数据时,SqlSession 类的实例对象就会将这次查询到的数据放到一级缓存中,在没有对该数据进行增加或者修改或者删除时,以后的查询均会从缓存中读取,而不会在重新连接数据库做查询。其原理图如下:

请输入图片描述

上图画出了 MyBatis 一级缓存的原理,当第一查询 id 为 1 的用户时,因为缓存中没有相应的数据,所以回去数据库进行查询,然后将查询到的结果放到一级缓存中,随后查询时,均会到缓存中读取,而不会再去数据库中查询。

当有修改、添加、和删除的操作时,就会把缓存中的原有数据进行清空,目的是为了保持缓存中的数据是最新的,避免数据脏读。当进行过修改、添加或删除时,因为缓存数据已经被清空,所以下一次的操作会去数据库查询,然后再放到缓存中。

0x04:MyBatis 二级缓存

一级缓存是基于同一个 SqlSession 类的实例对象的,有时候查询操作的方法会封装到一个 service 方法中,当查询操作完毕后,service 方法就会结束,这时候 SqlSession 类的实例化对象就关闭了,也就意味着一级缓存会被清空(因为一级缓存是基于 SqlSession 类的实例对象的)。如果再次调用 service 去查询同一个信息时,就会重新打开一个 SqlSession 类的实例对象,由于一级缓存中这时候是空的,所以便无法再从缓存中获取相关信息。

这时候就可以使用二级缓存,二级缓存是基于 Mapper 的,当有多个 SqlSession 类的实例对象去加载同一个 Mapper 文件,并执行其中的 sql 配置时,他们便会去共同使用一个 Mapper 缓存。二级缓存原理同一级缓存类似,如下图:

请输入图片描述

二级缓存相对于一级缓存来说范围会更大,其多个 SqlSession 类的实例对象回去共享一个 Mapper。一个 Mapper 都有自己的一个二级缓存区域,其中是按照 namespace 来划分的,当两个或多个 Mapper 的 namespace 相同时,那么这些 Mapper 所执行的 sql 就会被缓存到同一个二级缓存中。

0x05:如何开启二级缓存

一级缓存是默认开启的,而二级缓存则需要手动开启,首先需要在 MyBatis 的全局配置文件 SqlMapConfig.xml 中配置 setting 属性,设置 cacheEnabled 为 true,代码如下:

<setting name="cacheEnabled" value="true"/>

因为二级缓存是基于 Mapper 文件的,所以第二步就需要在相应的 Mapper 文件中做配置,只需要添加一个 <cache/> 标签即可,代码如下:

<cache/>

0x06:总结

一级缓存是基于 SqlSession,二级缓存是基于 Mapper 的,在二级缓存中是以 namespace 为单位的,不同 namespace 下的操作互不干扰。使用二级缓存要注意的是,要保证该 Mapper 下的数据不会在其他的 Mapper 文件中有缓存,否则会得到不正确的结果,如果必须要使用,建议使用拦截器判断执行 sql 涉及到哪些表,然后把相关表的缓存清空。


                                                                        公众号推荐:aFa攻防实验室

                         分享关于信息搜集、Web安全、内网安全、代码审计、红蓝对抗、Java、Python等方面的东西。

                                                                         

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值