Spring Cache
spring cache是一个框架,实现类基于注解的缓存功能,只需要简单的加一个注解,就能实现缓存功能,大大简化我们在业务中操作缓存的代码。
spring cache只是提供了一层抽象,底层可以切换不同的cache实现,具体就是通过cacheManager接口来统一不同的缓存技术。CacheManager是spring提供的各种缓存技术抽象接口。
针对不同的缓存技术需要实现不同的cacheManager
CacheManager | 描述 |
---|---|
EhCacheCacheManager | 使用EhCache作为缓存技术 |
GuavaCacheManager | 使用Google的GuavaCache作为缓存技术 |
RedisCacheManager | 使用Redis作为缓存技术 |
注解
在SpringCache中提供了很多缓存操作的注解,常见的是以下的几个:
注解 | 说明 |
---|---|
@EnableCaching | 开启缓存注解功能 |
@Cacheable | 在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中 |
@CachePut | 将方法的返回值放到缓存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用**@EnableCaching**开启缓存支持即可。使用Redis作为缓存技术,只需要导入Spring data Redis的maven坐标即可。
框架使用步骤:
导入pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
配置Redis的key的序列化器
// com.atguigu.spzx.cache.config;
@Configuration
public class RedisConfig {
@Bean
public CacheManager cacheManager(LettuceConnectionFactory connectionFactory) {
//定义序列化器
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
//过期时间600秒
.entryTtl(Duration.ofSeconds(600))
// 配置序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));
RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
3、在启动类上添加**@EnableCaching**注解
4、方法上添加**@Cacheable**注解
@Cacheable
1.作用:在方法执行前,spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据,若没有数据,调用方法并将方法返回值放到缓存中。
2.value:缓存的名称,每个缓存名称下面可以有多个key
3.key:缓存的key 支持spring的表达式语言SPEL语法
Spring 表达式语言(SpEL)
是一种在 Spring 框架中使用的表达式语言,它提供了一种在运行时对对象图进行查询和操作的强大方式。SpEL 的语法相对简洁且易于使用,其主要特点包括:
- 引用对象属性:使用
#{}
将属性名包裹起来,如#{user.name}
表示引用了user
对象的name
属性。 - 引用集合元素:使用
[]
语法引用集合中的元素,如#{userList[0]}
表示引用了userList
集合的第一个元素。 - 调用方法:可以使用
.
语法调用对象的方法,如#{user.getName()}
表示调用了user
对象的getName()
方法。 - 运算符:支持常见的数学运算符(
+
,-
,*
,/
)以及逻辑运算符(and
,or
,not
)等。 - 条件运算:支持三元条件运算符
condition ? trueValue : falseValue
。 - 正则表达式匹配:使用
matches
关键字进行正则表达式匹配。 - 集合选择:通过
.
语法对集合进行筛选,如#{userList.?[age > 18]}
表示从userList
中选择年龄大于 18 的用户。 - 投影运算:使用
.
语法对集合进行投影操作,如#{userList.![name]}
表示从userList
中提取所有用户的name
属性。 - Ternary 操作符:类似 Java 中的
?:
操作符,用于条件判断。 - 安全导航运算符:使用
?.
来避免 NPE(NullPointerException),如果属性为空,则不会抛出异常。
这些是 SpEL 中的一些主要语法特点,它提供了灵活而强大的功能,可以在 Spring 中的诸多场景下使用,如注解、配置文件、XML 配置等。 SpEL 的语法规则相对简洁清晰,使得开发者能够轻松地在 Spring 应用中进行对象图的操作和查询。
//首先根据key查询redis中的值并返回 如果redis中没有值,则返回当前方法返回的对象
@Override
@Cacheable(value = "userCache",key = "#userId")
public User findById(Long userId){
User user = new User();
user.setAge(18);
return user;
}
@CachePut
作用:将方法返回值,放入缓存
value:缓存的名称,每个缓存名称下面可以有很多key
key: 缓存的key 支持spring的表达式语言SPEL语法
当前UserController的save方法是用来保存用户信息的,我们希望在该用户信息保存到数据库的同事,也在缓存中缓存一份数据,我们可以在save方法上加上注解@CachePut,用法如下:
@CachePut(value = "userCache",key = "#user.userName")
public User saveUser(User user){
return user
}
key的写法如下:
#user.id: #user指的是方法形参的名称,id指的是user的id属性,也就是使用user的id属性作为key
#user.userName: #user指的是方法形参的名称,name指的是user的name属性,也就是使用user的name属性作为key
#result.id: #result代表方法返回值,该表达式代表以返回对象的id属性作为key
#result.userName:#result代表方法返回值,该表达式代表以返回对象的name属性作为key
@CacheEvit
作用:清理指定缓存
value:缓存的名称,每个缓存名称下面可以有多个key
key:缓存的key —>支持spring的表达式语言SPEL语法
当我们在删除数据库user表的数据的时候,我们需要删除缓存中对应的数据,此时就可以使用@CahceEvit注解,具体使用方式如下:
@CacheEvit(value = "userCache", key = "#userId")
public void deleteById(Long userId){
log.info("用户数据删除成功....")
}