首先我們需要設定一個快取管理器,然後才能使用快取註解來管理快取
package com.cherish.servicebase.handler; 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.CachingConfigurerSupport; 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.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisSerializer<String> redisSerializer = new StringRedisSerializer(); 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); template.setConnectionFactory(factory); //key序列化方式 template.setKeySerializer(redisSerializer); //value序列化 template.setValueSerializer(jackson2JsonRedisSerializer); //value hashmap序列化 template.setHashValueSerializer(jackson2JsonRedisSerializer); return template; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); 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); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration .defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) // 可以给每个cacheName不同的RedisCacheConfiguration 设置不同的过期时间 //.withCacheConfiguration("Users",config.entryTtl(Duration.ofSeconds(100))) .transactionAware() .build(); return cacheManager; } }
標記在方法或類別上,標識該方法或類別支持快取. Spring呼叫註解標識方法後會將回傳值快取到redis,以確保下次同條件呼叫該方法時直接從快取中取得回傳值。這樣就不需要再重新執行該方法的業務處理流程,提高效率。
@Cacheable常用的三個參數如下:
cacheNames 快取名稱
key 快取的key,需要注意key的寫法哈
condition 快取執行的條件,回傳true時候執行
範例
//查询所有用户,缓存到redis中 @GetMapping("/selectFromRedis") @Cacheable(cacheNames = "Users",key = "'user'") public ResultData getUserRedis(){ List<User> list = userService.list(null); return ResultData.ok().data("User",list); }
第一次查詢是從資料庫查詢的,然後快取到redis中使用redis視覺化工具查看快取的資訊
第二個查詢走了快取控制台沒有輸出,所以走的redis快取就是在redis中取得結果直接回傳。
標記在方法上,方法執行完畢後根據條件或key刪除對應的快取。常用的屬性:
allEntries boolean類型,表示是否需要清除快取中的所有元素
key 需要刪除的快取的key
//调用这个接口结束后,删除指定的Redis缓存 @PostMapping("updateUser") @CacheEvict(cacheNames ="Users",key = "'user'") public ResultData updateUser(@RequestBody User user){ String id = user.getId(); QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.eq("id",id); boolean b = userService.update(user, wrapper); return ResultData.ok().data("flag",b); }
//不删除redis缓存 @PostMapping("updateUser2") public ResultData updateUser2(@RequestBody User user){ String id = user.getId(); QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.eq("id",id); boolean b = userService.update(user, wrapper); return ResultData.ok().data("flag",b); }
當我們更新資料庫的資料時候,需要把redis的快取清空。否則我們查詢的資料是redis快取中的數據,這會導致資料庫和快取資料不一致的問題。
範例 呼叫沒有加 @CacheEvict 註解的介面修改數據,在查詢得到的數據是未修改之前的。
所以在我們呼叫修改資料的介面的時候需要清除快取
#加上@CacheEvict 註解清除對應的快取此時在查詢資料發現數據是最新的,跟資料庫保持一致。
我們已經實現了Spring Cache的基本功能,整合了Redis作為RedisCacheManger
,但眾所周知,我們在使用@Cacheable
註解的時候是無法給快取這是過期時間的。但有時候在一些場景中我們的確需要給快取一個過期時間!這是預設的過期時間
資料有效期限時間
#自訂過期時間
使用新的redis配置,再次查詢快取到資料看資料有效期
以上是springboot與redis整合中@Cacheable怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!