如果有遗漏,评论区告诉我进行补充
面试官: 说说Mybatis的缓存机制?
我回答:
在Java高级面试中,MyBatis的缓存机制是一个重要的话题。MyBatis是一个流行的Java持久化框架,它提供了强大的数据库访问能力和灵活的SQL映射配置。为了提高查询性能并减少数据库访问次数,MyBatis引入了缓存机制。下面将对MyBatis的缓存机制进行详细解释:
MyBatis缓存机制概述
MyBatis的缓存机制主要分为一级缓存和二级缓存。这两种缓存机制共同协作,以提高数据库的查询效率。
一级缓存
-
定义与特点:
- 一级缓存是SqlSession级别的缓存。
- 它默认开启且不可关闭。
- 每个SqlSession都有自己独立的缓存区域,缓存的生命周期与SqlSession一致。
-
工作原理:
- 当使用SqlSession进行查询时,如果下一次再使用相同的SqlSession进行查询,并且查询条件完全相同(包括SQL语句和参数),就会直接从缓存中取数据,而不是再次访问数据库。
- 当执行增删改操作(insert、update、delete)时,会清空一级缓存,因为增删改操作可能会改变数据库中的数据,为了保证数据的一致性,需要清空缓存。
- 打开 SqlSession:当
SqlSession
被打开时,使用CacheExecutor
包装Executor
。 - 执行查询:当执行查询时,
CacheExecutor
首先检查二级缓存是否有匹配的结果。 - 命中缓存:如果有匹配的结果,则直接返回缓存中的数据。
- 未命中缓存:如果没有匹配的结果,则执行 SQL 查询,并将结果放入二级缓存。
- 关闭 SqlSession:当
SqlSession
关闭时,二级缓存仍然存在,可供其他SqlSession
使用。
-
失效情况:
- 当SqlSession被关闭、提交或回滚时,一级缓存将失效。
- 执行了任何增删改操作后,一级缓存也会被清空。
- 如果查询语句不同或查询参数不同,一级缓存不会命中。
二级缓存
-
定义与特点:
- 二级缓存是Mapper级别的缓存。
- 它可以跨SqlSession共享数据。
- 二级缓存默认是关闭的,需要手动配置才能启用。
- 二级缓存适用于更大范围的数据共享,但由于缓存生命周期较长,可能导致缓存不一致问题。
-
工作原理:
- 在mapper.xml文件中添加
<cache/>
标签或在mapper接口上使用@CacheNamespace
注解来启用二级缓存。 - 当查询结果被存储在二级缓存中时,其他SqlSession可以直接从二级缓存中获取结果,而不需要再次访问数据库。
- 执行了增删改操作后,相关的二级缓存会失效。
- 在mapper.xml文件中添加
-
配置与启用:
- 在mapper.xml文件中添加
<cache/>
标签来开启二级缓存。 - 对于使用注解的mapper,在接口上使用
@CacheNamespace
注解也可以启用二级缓存。 - 可以配置缓存的回收策略、刷新间隔、缓存大小等参数,以适应不同的业务需求。
- 在mapper.xml文件中添加
-
注意事项:
- 使用二级缓存时,POJO类必须实现
Serializable
接口,因为二级缓存可能会将对象序列化到磁盘上。 - 二级缓存是线程共享的,因此需要考虑线程安全问题。
- 使用二级缓存时,POJO类必须实现
缓存的刷新与失效策略
-
缓存刷新:
- 执行增删改操作后,相关的缓存会失效,以确保数据的一致性。
- 可以配置缓存的刷新间隔,以定期刷新缓存。
-
失效策略:
- 除了增删改操作会导致缓存失效外,缓存的失效策略还包括LRU(最近最少使用)、FIFO(先进先出)等算法,这些算法可以根据缓存的使用情况来自动失效部分缓存。
最佳实践
- 合理使用缓存:根据业务需求决定是否启用缓存,避免不必要的缓存开销。
- 控制缓存范围:仅对读多写少的数据启用缓存,对于频繁更新的数据应禁用缓存。
- 定期清理缓存:在适当的时候手动清理缓存,以保持数据一致性。
- 监控缓存命中率:通过日志或监控工具监控缓存命中率,优化缓存策略。
- 分布式缓存:对于分布式系统,考虑使用 Redis 或 Memcached 等外部缓存系统。
综上所述,MyBatis的缓存机制包括一级缓存和二级缓存。一级缓存是SqlSession级别的缓存,默认开启且不可关闭;二级缓存是Mapper级别的缓存,需要手动配置才能启用。通过合理配置和使用这两种缓存机制,可以显著提高数据库的查询效率并减少数据库访问次数。
标签:面试题,缓存,二级缓存,查询,MyBatis,SqlSession,01,Mybatis,失效 From: https://blog.csdn.net/qq_43071699/article/details/145172757