文
章
目
录
章
目
录
Java面试题:谈一下MyBatis的缓存机制的理解
得分点
MyBatis一、二级缓存概念、区别
一级缓存和二级缓存是MyBatis中用于提高查询性能的两种缓存机制。
一级缓存(本地缓存):
- 一级缓存也被称为本地缓存,它默认启用且不能关闭。
- 一级缓存存在于SqlSession的生命周期中,即它是SqlSession级别的缓存。
- 在同一个SqlSession中查询时,MyBatis会将执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。
- 如果同一个SqlSession中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当Map缓存对象中已经存在该键值时,则会返回缓存中的对象。
二级缓存:
- 二级缓存存在于SqlSessionFactory的生命周期中,即它是SqlSessionFactory级别的缓存。
- 若要使用二级缓存,需要进行如下两处配置:
- 在MyBatis的全局配置settings中有一个参数cacheEnabled,这个参数是二级缓存的全局开关,默认值为true,初始状态为启用状态。
- MyBatis的二级缓存是和命名空间绑定的,即二级缓存需要配置在Mapper.xml映射文件中。在保证二级缓存的全局配置开启的情况下,给Mapper.xml开启二级缓存需要在Mapper.xml中添加相应配置。
二级缓存具有如下特性:
- 映射语句文件中的所有SELECT语句将会被缓存。
- 映射语句文件中的所有INSERT、UPDATE、DELETE语句会刷新缓存。
- 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
- 根据时间表(如noFlushInterval,没有刷新间隔),缓存不会以任何时间顺序来刷新。
- 缓存会存储集合或对象(无论查询方法返回什么类型的值)的1024个引用。
- 缓存会被视为read/write(可读/可写)的,意味着对象检索不是共享的,并且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
加分回答:
1)一级缓存失效的四种情况包括:
- SqlSession变了,缓存失效。
- SqlSession不变,查询条件不同,一级缓存失效。
- SqlSession不变,中间发生了增删改操作,一级缓存失效。
- SqlSession不变,手动清除缓存,一级缓存失效。
2)MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加细,能够到namespace级别,通过不同的Cache接口实现类的组合,对缓存的可控性也更强。
3)在多表查询时,MyBatis可能会出现脏数据的问题,这导致了安全使用二级缓存的条件比较苛刻。默认的MyBatis缓存实现都是基于本地的,这在分布式环境下可能会导致读取到脏数据的情况。因此,在分布式环境中,通常会选择使用Redis、Memcached等分布式缓存来替代MyBatis的二级缓存,以确保数据的一致性和可靠性。