一级缓存
一级缓存默认开启,不需要配置。
先说什么是SqlSession:
二级缓存
<!-- 通知 MyBatis 框架开启二级缓存 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
同时,需要在Mapper.xml文件中添加 <cache/>标签,表示对哪个mapper开启二级缓存。
二级缓存的作用域大于一级缓存,其作用域基于命名空间(namespace),它可以被多个SqlSession共享,生命周期较长,甚至在整个应用的生命周期内持续有效,除非被显式清理或超时。
简单来说,二级缓存就是缓存了很多个“一级缓存”,在开启二级缓存时,查出来的数据默认先存储在一级缓存中,当有 SqlSession关闭 时,它里面一级缓存中的数据就会被存储到Mapper的二级缓存中,这样该Mapper中的其他会话执行了相同方法时,就会在二级缓存中找到匹配的数据,如果没有找到,才会去数据库中查找。注意只有在该会话关闭时,它一级缓存中的数据才会被刷到二级缓存中。另外如果只是开启二级缓存的全局(config)开关,而会话(student)没有开启二级缓存,查询时也不会在二级缓存中查询。
二级缓存的键也是sql + 参数,值则为查询结果,缓存形式也是Map结构。
一二级缓存的实现原理

对于一级缓存从,每个SqlSession持有一个叫Executor的对象,而Executor又会持有一个Local Cache(本地缓存),当缓存命中,直接返回Local Cache中的数据,否则查询数据库,再将数据写入Local Cache。
而二级缓存则是在原来的Executor上,通过“装饰器设计模式”,在一级缓存之上新增了一个装饰器CacheExecutor,来进行全局缓存,共享粒度则控制到了namespace,即A-namespace中的缓存不对B-namespace开放,相互独立。
再说所有缓存对象的顶级接口:Cache
public interface Cache {
/**
* 缓存的唯一标识
*/
String getId();
/**
* 设置缓存,key-value键值对方式
*/
void putObject(Object key, Object value);
/**
* 根据key获取对应的缓存
*/
Object getObject(Object key);
/**
* 根据key移除对应的缓存
*/
Object removeObject(Object key);
/**
* 清空所有的缓存
*/
void clear();
/**
* 缓存中元素总数
*/
int getSize();
/**
* 读写锁
*/
ReadWriteLock getReadWriteLock();
}
Cache定义了缓存的基本操作,可以通过实现Cache接口的方式自定义缓存类。

被折叠的 条评论
为什么被折叠?



