Mybatis的缓存机制
缓存
缓存就是将用户经常查询的数据的结果保存在内存当中,这样用户再次查询数据时就可以直接通过缓存获取数据,而不需要通过磁盘读取数据。
缓存的分类
Mybatis提供了一级缓存和二级缓存。
- 一级缓存:一级缓存又叫本地缓存(默认开启,不允许关闭),用户保存用户在一次会话过程中查询的结果,用户一次会话中只能使用一个
sqlsession。 - 二级缓存:二级缓存又叫全局缓存,二级缓存是对一个表的结果的一个存储,可以共享给所用针对这张表查询的用户。
Executor

| 执行器 | 说明 |
|---|---|
| SimpleExecutor | 最简单的执行器,根据对应的sql直接执行,不会做额外的操作 |
| BatchExecutor | 通过批量操作来优化性能。执行批量更新时,由于内部有缓存的实现,使用完后需要调用flushStatements来清除缓存 |
| ReuseExecutor | 可重用的执行器,重用的对象是Statement,也就是说该执行器会缓存同一个sql的Statement,省去Statement的重新创建,优化性能。内部的实现通过一个HashMap来维护Statement对象。由于当前Map只在该session中有效,所以使用完后需要调用flushStatement来清除Map。 |
| CachingExecutor | 二级缓存使用的执行器。 |
一级缓存的原理

Mybatis使用一级缓存的流程:
- 用户发送指令到
Executor。 Executor根据用户需要执行的语句生成MappedStatement。Executor优先在LocalCache中查询是否有对应缓存。若有,则将缓存结果返回;若无,则从数据库中查询并获取数据并写入Local Cache。
sqlsession提交时会清空本地缓存,防止读取脏数据。
一级缓存失效的原因
- 同一个用户使用不同的
sqlsession。 - 同一个
sqlsession使用查询条件不同。 - 在同一次事务中进行了更新操作。
一级缓存注意事项
Mybatis一级缓存的本质时一个没有容量限定的HashMapMybatis和Spring整合后进行mapper代理开发,不支持一级缓存。
二级缓存原理

二级缓存通过在用户与Excutor中添加一个CachingExecutor实现
二级缓存的使用
-
通过注解
@CacheNamespace使用二级缓存。/* eviction: 使用的缓存策略 flushInterval: 周期刷新频率(ms) blocking: 请求时是否阻塞缓存 size: 缓存大小 */ @CacheNamespace(eviction = FifoCache.class,flushInterval = 3000,size = 512,blocking = false) -
通过
mapper.xml文件的cache标签配置二级缓存。<!--readOnly: 是否只读,若配置读写,则需要对应实体类能够序列化--> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
Cache类

| Cache类型 | 说明 |
|---|---|
| LruCache | 使用最近最久未使用算法淘汰缓存。 |
| FifoCache | 使用先进先出淘汰缓存。 |
| SynchronizedCache | 同步Cache,实现比较简单,注解使用synchronized修饰方法。 |
| LoggingCache | 日志功能,装饰类,用于记录缓存的命中率,如果开启了DEBUG模式,则会输出命中率日志。 |
| SerializedCache | 序列化功能,将值序列化后存入缓存中,该功能用户缓存返回示例的Cope,用于保存线程安全。 |
| PerpetualCache | 最基础的缓存类,底层实现比较简单,直接使用HashMap |
| SoftCache | 软引用回收缓存。 |
| WeakCache | 弱引用回收缓存。 |
在xml文件中的、、等标签中可以设置flushCache选择是否刷新缓存,useCache选择是否使用缓存。
<select flushCache="true" useCache="true">
{sql}查询语句
</select>
二级缓存失效的原因
xml
{sql}查询语句
### 二级缓存失效的原因
`flushCache`属性在增删查改中的使用。
3万+

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



