MyBatis一级、二级缓存深入理解
发布时间: 2024-05-02 09:26:01 阅读量: 84 订阅数: 39
![MyBatis实战指南](https://img-blog.csdnimg.cn/7380bff0905f4a0fa160fc4ce4983861.png)
# 1. MyBatis 缓存概述**
MyBatis 缓存是一种机制,它允许在应用程序中存储经常访问的数据,以提高性能。MyBatis 缓存分为一级缓存和二级缓存。一级缓存是本地缓存,存储在会话级别,而二级缓存是全局缓存,存储在应用级别。
# 2. 一级缓存(本地缓存)
### 2.1 一级缓存的原理和机制
MyBatis 的一级缓存是一个本地缓存,它存储在每个会话中。当一个查询被执行时,MyBatis 会将查询结果存储在本地缓存中。如果后续的查询与之前的查询相同,MyBatis 会直接从本地缓存中读取结果,而不会再执行数据库查询。
一级缓存的机制如下:
- 当一个查询被执行时,MyBatis 会根据查询的 SQL 语句和参数生成一个缓存键。
- 缓存键用于标识查询结果。
- 如果缓存中存在与缓存键匹配的查询结果,MyBatis 会直接从缓存中读取结果。
- 如果缓存中不存在与缓存键匹配的查询结果,MyBatis 会执行数据库查询并存储结果到缓存中。
### 2.2 一级缓存的配置和使用
一级缓存的配置和使用可以通过以下方式进行:
- **开启一级缓存:**默认情况下,一级缓存是开启的。可以通过在 MyBatis 配置文件中设置 `cacheEnabled` 属性为 `true` 来显式开启一级缓存。
- **设置缓存大小:**可以通过在 MyBatis 配置文件中设置 `localCacheScope` 属性来设置一级缓存的大小。默认情况下,缓存大小为 1024。
- **刷新缓存:**可以通过调用 `SqlSessionFactory.clearCache()` 方法来刷新一级缓存。
### 2.3 一级缓存的失效策略
一级缓存的失效策略决定了当查询结果发生变化时,缓存中的结果是否仍然有效。MyBatis 提供了以下失效策略:
- **LRU(最近最少使用):**当缓存达到最大容量时,会删除最近最少使用的缓存项。
- **FIFO(先进先出):**当缓存达到最大容量时,会删除最早添加的缓存项。
- **SOFT:**当 JVM 内存不足时,会删除缓存项。
- **WEAK:**当 JVM 内存不足时,会立即删除缓存项。
默认情况下,一级缓存使用 LRU 失效策略。
# 3. 二级缓存(全局缓存)**
### 3.1 二级缓存的原理和机制
二级缓存是全局缓存,作用域为整个应用。当一个查询结果被放入二级缓存后,所有线程都可以访问该缓存结果,从而避免了重复查询数据库。
二级缓存的实现原理是将查询结果存储在内存中,并使用一个缓存管理器来管理缓存。缓存管理器负责缓存的加载、获取、更新和失效。
### 3.2 二级缓存的配置和使用
要启用二级缓存,需要在 MyBatis 配置文件中配置 `<cache>` 元素。`<cache>` 元素的属性如下:
| 属性 | 描述 |
|---|---|
| `type` | 缓存实现类,默认是 `org.apache.ibatis.cache.impl.PerpetualCache` |
| `eviction` | 失效策略,默认是 `LRU` |
| `flushInterval` | 刷新间隔,单位为毫秒,默认是 60000 |
| `size` | 缓存大小,默认是 1024 |
| `readWrite` | 是否允许读写,默认是 true |
示例配置:
```xml
<cache type="org.apache.ibatis.cache.impl.PerpetualCache" eviction="LRU" size="1024" readWrite="true" />
```
### 3.3 二级缓存的失效策略
二级缓存的失效策略决定了当缓存数据发生变化时,如何从缓存中移除过期的缓存数据。MyBatis 提供了多种失效策略,包括:
- **LRU (Least Recently Used)**:移除最近最少使用的缓存数据。
- **FIFO (First In First Out)**:移除最先放入缓存的缓存数据。
- **SOFT**:当内存不足时,JVM 会自动移除缓存数据。
- **WEAK**:当 GC 运行时,JVM 会自动移除缓存数据。
默认的失效策略是 LRU,它可以有效地平衡缓存命中率和内存消耗。
### 代码示例
以下代码示例演示了如何使用二级缓存:
```java
@CacheNamespaceRef(AuthorCache.class)
public interface AuthorMapper {
@Select("SELECT *
```
0
0