作者 | 涅槃重生
www.cnblogs.com/maolinjava/p/12335861.html
前言
Spring Cache 是 Spring 3 版本之後引入的一項技術,可以簡化對於緩存層的操作,spring cache與springcloud stream類似,都是基於抽象層,可以任意切換其實現。其核心是CacheManager、Cache這兩個接口,所有由spring整合的cache都要實現這兩個接口、Redis的實現類則是 RedisCache 和 RedisManager。
使用
1、查詢
需要導入的依賴
<code>1 <dependency>
2 <groupid>org.springframework.boot/<groupid>
3 <artifactid>spring-boot-starter-cache/<artifactid>
4 /<dependency>
5 <dependency>
6 <groupid>org.springframework.boot/<groupid>
7 <artifactid>spring-boot-starter-data-redis/<artifactid>
8 /<dependency>/<code>
編寫對於cache的配置
<code>1 @EnableCaching
2 @SpringBootConfiguration
3 public class CacheConfig {
4
5 @Autowired
6 private RedisConnectionFactory connectionFactory;
7
8 @Bean // 如果有多個CacheManager的話需要使用@Primary直接指定那個是默認的
9 public RedisCacheManager cacheManager() {
10 RedisSerializer<string> redisSerializer = new StringRedisSerializer();
11 Jackson2JsonRedisSerializer<object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
12
13 ObjectMapper om = new ObjectMapper();
14 // 防止在序列化的過程中丟失對象的屬性
15 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
16 // 開啟實體類和json的類型轉換
17 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
18 jackson2JsonRedisSerializer.setObjectMapper(om);
19
20 // 配置序列化(解決亂碼的問題)
21 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
22 // 不緩存空值
23 .disableCachingNullValues()
24 // 1分鐘過期
25 .entryTtl(Duration.ofMinutes(1))
26 ;
27 RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
28 .cacheDefaults(config)
29 .build();
30 return cacheManager;
31 }
32 }/<object>/<string>/<code>
進行以上配置即可使用springboot cache了,還有一個key的生成策略的配置(可選)
<code>1 @Bean
2 public KeyGenerator keyGenerator() {
3 return (target, method, params) -> {
4 StringBuffer key = new StringBuffer();
5 key.append(target.getClass().getSimpleName() + "#" + method.getName() + "(");
6 for (Object args : params) {
7 key.append(args + ",");
8 }
9 key.deleteCharAt(key.length() - 1);
10 key.append(")");
11 return key.toString();
12 };
13 }/<code>
注意:如果配置了KeyGenerator ,在進行緩存的時候如果不指定key的話,最後會把生成的key緩存起來,如果同時配置了KeyGenerator 和key則優先使用key。
在controller或者service的類上面添加 @CacheConfig ,註解裡面的參數詳情見下表:
在標有@CacheConfig的類裡面編寫一個查詢單個對象的方法並添加 @Cacheable註解。
<code>1 @Cacheable(key = "#id", unless = "#result == null")
2 @PatchMapping("/course/{id}")
3 public Course courseInfo(@PathVariable Integer id) {
4 log.info("進來了 .. ");
5 return courseService.getCourseInfo(id);
6 }/<code>
執行完該方法後,執行結果將會被緩存到Redis:
@Cacheable註解中參數詳情見下表:
2、 修改
編寫一個修改的方法,參數傳對象,返回值也改成這個對象
<code>1 @PutMapping("/course")
2 public Course modifyCoruse(@RequestBody Course course) {
3 courseService.updateCourse(course);
4 return course;
5 }/<code>
在方法上面添加 @CachePut(key = "#course.id") 註解,這個註解表示將方法的返回值更新到緩存中,註解中的參數和 @Cacheable 中的一樣,這裡就略過了。
3、 刪除
編寫刪除方法,在方法上添加@CacheEvict 註解
<code>1 @CacheEvict(key = "#id")
2 @DeleteMapping("/course/{id}")
3 public void removeCourse(@PathVariable Integer id) {
4 courseService.remove(id);
5 }/<code>
@CacheEvict 的參數信息見下表:
基於代碼的 Cache 的使用
因為我們有配置的CacheManager,所以可以利用RedisCacheManager對象去手動操作cache,首先將CacheManager注入進來:
<code>1 @Resource
2 private CacheManager cacheManager;
3
4 @PatchMapping("/course2/{id}")
5 public Course course2(@PathVariable Integer id) {
6 // 獲取指定命名空間的cache
7 Cache cache = cacheManager.getCache("course");
8 // 通過key獲取對應的value
9 Cache.ValueWrapper wrapper = cache.get(2);
10 if (wrapper == null) {
11 // 查詢數據庫
12 Course course = courseService.getCourseInfo(id);
13 // 加入緩存
14 cache.put(course.getId(), course);
15 return course;
16 } else {
17 // 將緩存的結果返回
18 // 因為配置了enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
19 // 所以在進行強轉的時候不會報錯
20 return (Course) wrapper.get();
21 }
22 }/<code>
閱讀更多 楠哥教你學Java 的文章