自学内容网 自学内容网

高级java每日一道面试题-2024年9月19日-框架篇[Mybatis篇]-说一下mybatis的一级缓存和二级缓存?

如果有遗漏,评论区告诉我进行补充

面试官: 说一下mybatis的一级缓存和二级缓存?

我回答:

在MyBatis中,缓存机制是一个重要的特性,它可以帮助减少数据库的访问次数,从而提高应用的性能。MyBatis提供了两级缓存:一级缓存(也称为Session级缓存)和二级缓存(也称为跨Session缓存或映射器级别的缓存)。下面将详细解释这两种缓存机制。

一级缓存(Session级缓存)

概述
  • 一级缓存是默认开启的,它是基于SqlSession级别的缓存。
  • 每个SqlSession对象都有自己的缓存空间,这个缓存是私有的,不同SqlSession之间的缓存互不影响。
工作原理
  • 当一个查询被执行时,MyBatis首先会检查一级缓存中是否存在该查询的结果。
  • 如果存在,则直接返回缓存中的结果,避免了对数据库的重复访问。
  • 如果不存在,则执行查询并将结果存入一级缓存中,供后续相同查询使用。
缓存失效情况
  • 当执行SQL语句进行增删改操作(INSERT、UPDATE、DELETE)时,MyBatis会清空当前SqlSession的一级缓存,因为增删改操作可能会影响到缓存中数据的一致性。
  • 当执行不同的SqlSession时,每个SqlSession都有自己独立的一级缓存,它们之间互不影响。
  • 手动调用SqlSession的clearCache()方法也会清空一级缓存。
缓存实现
  • MyBatis的一级缓存通常使用PerpetualCache(一种简单的基于HashMap的缓存)实现,但也可以配置为使用其他缓存实现,如FIFOCache(先进先出缓存)或LRUCache(最近最少使用缓存)等。
优点
  • 提高了查询性能,减少了数据库访问次数。
  • 实现简单,默认开启,无需额外配置。
缺点
  • 只在同一个SqlSession内有效,跨SqlSession无法共享缓存。
  • 更新操作会导致整个缓存被清空,可能会导致缓存命中率降低。

二级缓存(跨Session缓存/全局缓存)

概述
  • 二级缓存是基于namespace级别的缓存,可以被多个SqlSession共享。二级缓存是跨SqlSession的,它的作用域是Mapper(映射器)的命名空间。这意味着,同一个Mapper映射的多个SqlSession之间可以共享缓存数据。
  • 二级缓存是可选的,需要显式地开启,并且要确保序列化支持。
工作原理
  • 当一个查询被执行时,MyBatis首先会检查二级缓存中是否存在该查询的结果。
  • 如果存在,则直接返回缓存中的结果。
  • 如果不存在,则执行查询并将结果存入二级缓存中,供后续相同查询使用。
配置步骤
  1. 开启二级缓存

    • mybatis-config.xml文件中设置<setting name="cacheEnabled" value="true"/>
    • 在映射文件(如Mapper.xml)中添加<cache/>标签来启用二级缓存。
  2. 序列化支持

    • 确保实体类实现了Serializable接口,以便于对象可以被序列化并存储在缓存中。
  3. 控制缓存行为

    • 可以通过<cache>标签的属性来控制缓存的行为,例如设置缓存过期时间、读写策略,eviction(回收策略)、flushInterval(刷新间隔)、size(引用数目)等。
    • 也可以通过<select><insert><update><delete>标签上的useCacheflushCache属性来控制特定语句是否使用缓存以及是否刷新缓存。
缓存失效情况
  • 与一级缓存类似,执行增删改操作也会使二级缓存失效。
  • 当SqlSession关闭或提交时,MyBatis会尝试将二级缓存中的数据写回到数据库(这取决于配置的flushCache属性),并清空当前SqlSession中的一级缓存。
  • 不同的Mapper之间,如果开启了二级缓存,它们之间也可以共享缓存数据,但前提是这些Mapper的缓存配置要兼容。
  • 调用了clearCache()方法手动清空缓存。
  • 根据配置的缓存策略,如过期时间到达时,缓存会被自动清空。
注意事项
  • 二级缓存中的数据是跨SqlSession的,因此必须保证缓存数据的序列化(因为缓存数据可能存储在磁盘或其他介质上)。
  • 二级缓存可能会引起脏读等问题,因为缓存的数据可能不是最新的(尽管有刷新机制,但依然存在风险)。
优点
  • 可以在多个SqlSession之间共享缓存,提高了整体应用的性能。
  • 提供了更多的配置选项,可以根据需求灵活调整缓存行为。
缺点
  • 需要显式配置,增加了开发复杂度。
  • 更新操作会导致整个namespace下的缓存被清空,可能会影响缓存命中率。
  • 对象必须实现Serializable接口,增加了序列化的开销。

总结

  • 一级缓存是默认开启的,基于SqlSession级别的缓存,适用于单个SqlSession内的多次查询。
  • 二级缓存是基于namespace级别的缓存,需要显式开启,可以在多个SqlSession之间共享,适用于跨SqlSession的查询。

在面试中,能够清晰地解释MyBatis的一级缓存和二级缓存的工作原理、配置方式以及各自的优缺点,将有助于展示你对MyBatis框架的理解和技术深度。此外,实际项目经验也是面试官非常看重的部分,因此准备好相关的项目案例来说明你的实践经历也是非常有帮助的。


原文地址:https://blog.csdn.net/qq_43071699/article/details/142373386

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!