1.项目情况

简述自己做过的项目

2. myBatis 的多级缓存 --有两级缓存

2.1 一级缓存

描述:会话级缓存,该缓存生命周期仅存于该会话,不可直接关闭

命中场景:

1.满足特定命中参数

a.SQL与参数相同 b.同一个会话 c.相同的MapperStatement ID d.RowBounds行范围相同

2.不触发清空方法

a. 手动调用clearCache b. 执行提交回滚 c. 执行update d. 配置flushCache=true e. 缓存作用域为Statement

最终实现:就是一个hsahMap

执行如下方法会触发清空方法

a. update:执行任意增删改
b. select:查询又分为两种情况,前置清空 -> flushCache=true 另一个则是后置清空,配置了缓存作用域为Statement查询结束会清空缓存
c. commit:提交前清空
d. rollback : 回滚前清空

一级缓存失效的问题

整合Spring时,会发生失效。原因:Spring对SqlSession进行了封装通过SqlSessionTemplate,使得每次调用SQL都会创建一个SqlSession,具体可以参见SqlSessionInterceptor,一级缓存是在同一个会话中才会生效!

解决方案:Spring添加事务,可解决该问题。

2.2 二级缓存

描述:应用级性缓存,缓存对象存在于整个应用周期,而且可以跨线程使用。

与一级缓存不同的是它的作用域范围是整个应用,而且可以跨线程使用,所有二级缓存会有更高的命中率,适合缓存一些修改较少的 数据,数据访问流程上说先访问二级缓存,在访问一级缓存

缓存数据保存在:a. 内存,最简单,而且速度快。弊端是不能持久化,而且容量有限制。

b. 磁盘,可以持久化,容量大。但速度不如内存,一般结合内存使用。

c. 第三方集成,分布式情况,如果和其他节点共享缓存,只能第三方软件集成。比如redis.

溢出淘汰:当容量满的时候清除,清除掉算法即溢出淘汰机制。

实现:Mybatis抽象出Cache接口,其只定义了缓存中最基本

设置缓存-获取缓存-清除缓存-获取缓存数量

二级缓存默认不开启,需要为其声明缓存空间才可使用。通过@CacheNamespace或指定的MappedStatement声明之后该缓存为该Mapper所独有,其他Mapper不能访问。如需多个Mapper共享一个缓存空间可以通过@CacheNamespaceRef或引用同一个缓存空间