当前位置 博文首页 > GooReey的博客:【MyBatis 3】MyBatis一级缓存和二级缓存

    GooReey的博客:【MyBatis 3】MyBatis一级缓存和二级缓存

    作者:[db:作者] 时间:2021-08-30 22:22

    一、什么是缓存

    缓存是存在于内存中的临时数据。
    使用缓存减少和数据库的交互次数,提高执行效率。

    1、适用于缓存

    • 经常查询并且不经常改变的;
    • 数据的正确与否对最终结果影响不大的;

    2、不适用于缓存

    • 经常改变的数据;
    • 数据的正确与否对最终结果影响很大的;
    • 例如:商品的库存,银行的汇率,股市的牌价;

    二、mybatis一级缓存

    1、一级缓存简介

    一级缓存作用域是sqlsession级别的,同一个sqlsession中执行相同的sql查询(相同的sql和参数),第一次会去查询数据库并写到缓存中,第二次从一级缓存中取。

    一级缓存是基于 PerpetualCache 的 HashMap 本地缓存,默认打开一级缓存。

    2、何时清空一级缓存

    如果中间sqlSession去执行commit操作(执行插入、更新、删除),则会清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

    一级缓存时执行commit,close,增删改等操作,就会清空当前的一级缓存;当对SqlSession执行更新操作(update、delete、insert)后并执行commit时,不仅清空其自身的一级缓存(执行更新操作的效果),也清空二级缓存(执行commit()的效果)。

    3、一级缓存无过期时间,只有生命周期

    MyBatis在开启一个数据库会话时,会创建一个新的SqlSession对象,SqlSession对象中会有一个Executor对象,Executor对象中持有一个PerpetualCache对象,见下面代码。当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

    三、mybatis二级缓存

    1、二级缓存简介

    它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

    二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

    2、二级缓存何时存入

    在关闭sqlsession后(close),才会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。

    开启了二级缓存后,还需要将要缓存的pojo实现Serializable接口,为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中。

    3、二级缓存有过期时间,但没有后台线程进行检测

    需要注意的是,并不是key-value的过期时间,而是这个cache的过期时间,是flushInterval,意味着整个清空缓存cache,所以不需要后台线程去定时检测。

    每当存取数据的时候,都有检测一下cache的生命时间,默认是1小时,如果这个cache存活了一个小时,那么将整个清空一下。

    4、当 Mybatis 调用 Dao 层查询数据库时,先查询二级缓存,二级缓存中无对应数据,再去查询一级缓存,一级缓存中也没有,最后去数据库查找。

    往期精彩内容:

    Java知识体系总结

    Spring框架总结

    超详细的springBoot学习笔记

    常见数据结构与算法整理总结

    Java设计模式:23种设计模式全面解析

    Java面试题总结(附答案)

    Linux知识体系总结

    Redis知识体系总结

    cs