目录
1 概述
2 @Cacheable注解使用详细介绍
2.1 @Cacheable注解使用
2.2 Cacheable 注解的属性
1 概述
Spring高版本引入了cache的注解技术。该技术是一种规范。Redis的cache技术,底层使用的是Spring Data Redis。cache技术的使用需要掌握的有@EnableCaching、@Cacheable、@CacheEvict、@Caching、@CacheConfig注解的使用,这些注解支持SpringSPEL表达式方式。
今天先了解@Cacheable注解。
2 @Cacheable注解使用详细介绍 2.1 @Cacheable注解使用
步骤一:cacheConfig配置类
package com.liubujun.redis_springboot.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializationContext;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;import java.util.HashMap;import java.util.Map;@Configuration@EnableCachingpublic class CacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){ RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(defaultCacheConfig(10000)) .withInitialCacheConfigurations(initCacheConfigMap()) .transactionAware() .build(); return redisCacheManager; } private RedisCacheConfiguration defaultCacheConfig(Integer second) { Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); //配置序列化 解决乱码的问题 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(second)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializevaluesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); return config; } private Map
步骤二:application.properties文件配置redis的参数
#redis服务器地址(自己redis所在主机地址)spring.redis.host=*******#redis服务器连接端口spring.redis.port=6379#redis数据库索引(默认是0)spring.redis.database=0#连接超时时间spring.redis.timeout=1800000#连接池最大连接数(使用负值表示没有限制)spring.redis.lettuce.pool.max-active=20#最大阻塞等待时间(负数表示没有限制)spring.redis.lettuce.pool.max-wait=-1#连接池中最大空闲连接spring.redis.lettuce.pool.max-idle=5#连接池中最小空闲连接spring.redis.lettuce.pool.min-idle=0
步骤三:测试类编写
package com.liubujun.redis_springboot.controller;import com.liubujun.redis_springboot.entity.User;import org.springframework.cache.annotation.Cacheable;import org.springframework.cache.annotation.EnableCaching;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController@RequestMapping("/redisTest")public class TestController { @GetMapping("/cache/{id}") @Cacheable(cacheNames = "User",key = "#id") //此时缓存中的key为id,value为查询出来的数据(#id就表示取出参数id的值作为key) public User findUserById(@PathVariable("id") Integer id){ User user = new User(); user.setId(id); user.setName("测试:springBooth中Cache"+id+"查询时间戳"+System.currentTimeMillis()); System.out.println("模拟数据库查询数据id:"+id+"name:"+user.getName()); return user; }}
步骤四:浏览器访问
相同id连续两次访问接口
控制台只有一句输出语句:
redis客户端中存储的值:
我将用相同的id连续访问两次,控制台只有一句输出语句,那么就说明:第一次访问走了代码逻辑并且将返回结果放入了cacheable中。第二次直接从缓存中取出的数据,没有走代码逻辑。体检了cacheable的作用。
总结: @Cacheable 注解可以将运行结果缓存,以后查询相同的数据,直接从缓存中调取,不需要调用方法,换言之:在方法上加了@Cacheable 注解后,每次调用该方法,都会先检查缓存中有没有相同的key,如果有直接从缓存中获取,没有再调用具体代码逻辑。
2.2 Cacheable 注解的属性
cacheNames/value :用来指定缓存组件的名字
key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)
keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用
cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
condition :可以用来指定符合条件的情况下才缓存
unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)
sync :是否使用异步模式。
cacheNames/value :用来指定缓存组件的名字
key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)
keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用
cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
condition :可以用来指定符合条件的情况下才缓存
unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)
sync :是否使用异步模式。
1)cacheNames/value :
用来指定缓存组件的名字,将方法的返回结果放在哪个缓存中,可以是数组的方式
@GetMapping("/cache/{id}")@Cacheable(cacheNames = "User") //也可以这样写@Cacheable(cacheNames {"User","Users"})public User findUserByIds(@PathVariable("id") Integer id){ User user = new User(); user.setId(id); user.setName("测试:springBooth中Cache"+id+"查询时间戳"+System.currentTimeMillis()); System.out.println("模拟数据库查询数据id:"+id+"name:"+user.getName()); return user;}
2)key :
缓存数据时使用的key。默认使用的是方法参数的值,也可以使用spEL表达式编写
@GetMapping("/cache/{id}")@Cacheable(cacheNames = "User",key = "#root.methodName+'[' + #id + ']'") //这时如果传入的id为500,那么key=findUserById[500]public User findUserById(@PathVariable("id") Integer id){ User user = new User(); return user;}
3)keyGenerator :
key的生成器,可以用自己指定的生成器去生成key
4)condition :
符合条件的情况下才进行缓存
@GetMapping("/cache/{id}")@Cacheable(cacheNames = "User",condition = "#id >1 ") //这里表示id值大于1时才进行缓存public User findUserByIds(@PathVariable("id") Integer id){ User user = new User(); return user;}
5)unless :
否定缓存,当unless指定的条件为true时,方法的返回值不会被缓存
@GetMapping("/cache/{id}")@Cacheable(cacheNames = "User",unless = "#id >1 ") //这里表示id值大于1时不会进行缓存public User findUserByIds(@PathVariable("id") Integer id){ User user = new User(); return user;}
6)sync :
是否使用异步模式,默认是方法执行完后,以同步的方式将方法返回的结果存在缓存中
参考博客:SpringBoot 缓存之 @Cacheable 详细介绍_勇往直前的专栏-CSDN博客_@cacheable