一、Spring Cache介绍
Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。
CacheManager是Spring提供的各种缓存技术抽象接口。
针对不同的缓存技术需要实现不同的CacheManager:
| CacheManager | 描述 |
|---|---|
| EhCacheCacheManager(用的多) | 使用EhCache作为缓存技术 |
| GuavaCacheManager | 使用Google的GuavaCache作为缓存技术 |
| RedisCacheManager | 使用Redis作为缓存技术 |
Spring Cache jar包导入
基础功能:
在start-web依赖下的spring-webmvc下的spring-context中
整合缓存工具:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
二、Spring Cache常用注解
| 注解 | 说明 |
|---|---|
| @EnableCaching | 开启缓存注解功能 |
| @Cacheable | 在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中 |
| @CachePut | 将方法的返回值放到缓存中 |
| @CacheEvict | 将一条或多条数据从缓存中删除 |
在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用@EnableCaching开启缓存支持即可。
例如,使用Redis作为缓存技术,只需要导入Spring data Redis的maven坐标即可。
Spring Cache根据pom.xml中导入何种缓存依赖,确定使用缓存方式。
三、使用方式
1.使用基本的功能
注入CacheManager,底层默认使用ConcurrentMap实现缓存;实现类为ConcurrentMapCacheManager
1.1@EnableCaching 开启缓存注解功能
该注解添加在启动类上
1.2 @CachePut 方法的返回值放到缓存中
/**
CachePut:将方法返回值放入缓存
value:缓存的名称(根据存入方法对key分类),每个缓存名称下面可以有多个key
key:缓存的key,注解中key可以用#加user.id获取方法完成后的返回值,必须保证user和接收的user一样
*/
@CachePut (value = "userCache", key = "#user.id")
@PostMapping
public User save(User user){
userService.save (user);
return user;
}
1.3@CacheEvict 一条或多条数据从缓存中删除
/**
清理指定缓存
@CacheEvict:在删除时传入key
#id保持和传入参数一致
#p是默认,后面0指传入的第一个参数
*/
//@CacheEvict(value ="userCache",key = "#id")
//@CacheEvict(value ="userCache",key = "#root.args[0]")
@CacheEvict(value ="userCache",key = "#p0")
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id){
userService. removeById(id);
}
1.4 @Cacheable
存在缓存是不会进入方法的,直接将缓存返回;如果方法内存在断点,在有缓存情况下不会触发;
/**
先看是否存在缓存,有直接返回,没有查,存入缓存
存在缓存是不会进入方法的,直接将缓存返回
condition:条件,满足时才缓存数据(但是可以不加,无效id缓存空key可以解决缓存穿透问题)
unless = "#result == null" 为空时,不缓存
*/
//@Cacheable(value ="userCache",key ="#id" condition = "#result != null")存在问题,condition不能直接使用返回结果
@Cacheable(value ="userCache",key ="#id" unless = "#result == null")
@GetMapping("/{id}")
public User getById(@PathVariable Long id){
User user = userService.getById(id);
return user;
}
@Cacheable (value = "userCache", key = "#user. id + ‘_’ + #user.name")
1.4.1 存在缓存击穿现象
传入不存在的id,数据库查不到,但会被存入缓存中,导致双方数据不一致。
缓存击穿:全打在一个缓存上;访问热点key
缓存穿透:访问不存在的key,查不到缓存开始请求数据库,无效请求通过缓存访问到数据库
2.整合Redis
redis:
host: 172.17.2.00
port: 6379
password: root@123
database: 0
cache:
redis:
time-to-live: 180000 #缓存过期时间,自行设置
使用方法同上:
Record Date :2023/03/26