微服务实战——SpringCache 整合 Redis

news/2024/10/7 16:59:54/

SpringCache 整合 Redis

1.配置

spring.cache.type=redis
@EnableCaching
@EnableFeignClients(basePackages = "com.cwh.gulimall.product.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallProductApplication {public static void main(String[] args) {SpringApplication.run(GulimallProductApplication.class, args);}}

2.使用

// 需要指定放入哪个名字的缓存(分区)
@Cacheable({"category"})  // 代表当前方法的结果需要缓存,如果缓存中有,不用调用方法;如果缓存中没有,调用方法后将结果放入缓存
@Override
public List<CategoryEntity> getLevel1Categories() {return list(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
}

3.@Cacheable细节设置

1.缓存到Redis中数据具有如下的特点:

  • 如果缓存中有,方法不会被调用;
  • key默认自动生成;形式为"缓存的名字::SimpleKey ";
  • 缓存的value值,默认使用jdk序列化机制,将序列化后的数据缓存到redis
  • 默认ttl时间为-1,表示永不

2.然而这些并不能够满足我们的需要,我们希望:

  • 能够指定生成缓存所使用的key;
  • 指定缓存的数据的存活时间;
  • 将缓存的数据保存为json形式

针对于第一点,使用@Cacheable注解的时候,设置key属性,接受一个SpEL(Spring Expression Language):

@Cacheable(value = {"category"},key = "'level1Categorys'")

针对于第二点,在配置文件中指定ttl:

  cache:type: redisredis:time-to-live: 3600000
// 需要指定放入哪个名字的缓存(分区)@Cacheable(value = {"category"},key = "#root.method.name")  // 代表当前方法的结果需要缓存,如果缓存中有,不用调用方法;如果缓存中没有,调用方法后将结果放入缓存@Overridepublic List<CategoryEntity> getLevel1Categories() {return list(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));}@Cacheable(value = {"category"},key = "#root.methodName")@Overridepublic Map<String, List<Catelog2Vo>> getCatalogJson() {/*** 优化循环查库*/List<CategoryEntity> list = this.list();// 1.查出所有1级分类List<CategoryEntity> level1List = getParentCid(list, 0L);// 2.封装数据Map<String, List<Catelog2Vo>> parentCid = level1List.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {// 2.1.查到该一级分类的二级分类List<CategoryEntity> level2List = getParentCid(list, v.getCatId());List<Catelog2Vo> catelog2Vos = null;if (level2List != null) {catelog2Vos = level2List.stream().map(c2 -> {Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, c2.getCatId().toString(), c2.getName());// 2.2.查到该二级分类对应的三级分类,并封装为voList<Catelog2Vo.Catelog3Vo> catelog3List = getParentCid(list, c2.getCatId()).stream().map(c3 -> new Catelog2Vo.Catelog3Vo(catelog2Vo.getId(),c3.getCatId().toString(),c3.getName())).collect(Collectors.toList());catelog2Vo.setCatalog3List(catelog3List);return catelog2Vo;}).collect(Collectors.toList());}return catelog2Vos;}));return parentCid;}

4.自定义缓存配置——如何将数据以JSON的形式缓存到Redis

  1. 这涉及到修改缓存管理器的设置,CacheAutoConfiguration导入了RedisCacheConfiguration,而RedisCacheConfiguration中自动配置了缓存管理器RedisCacheManager,而RedisCacheManager要初始化所有的缓存,每个缓存决定使用什么样的配置,如果RedisCacheConfiguration有就用已有的,没有就用默认配置。
  2. 想要修改缓存的配置,只需要给容器中放一个“redisCacheConfiguration”即可,这样就会应用到当前RedisCacheManager管理的所有缓存分区中。
package com.cwh.gulimall.product.config;import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {/*** 配置文件中的东西没有用到* 1、原来和配置文件绑定的配置类是这样的* @ConfigurationProperties(prefix="spring.cache")* public class CacheProperties* 2、让他生效* @EnableConfigurationProperties(CacheProperties.class)* @return*/@BeanRedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));// 在Redis中放入自动配置类,设置JSON序列化机制config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));// 将配置文件中的所有配置都生效CacheProperties.Redis redisProperties = cacheProperties.getRedis();// 设置配置文件中的各项配置,如过期时间if (redisProperties.getTimeToLive() != null) {config = config.entryTtl(redisProperties.getTimeToLive());}if (redisProperties.getKeyPrefix() != null) {config = config.prefixKeysWith(redisProperties.getKeyPrefix());}if (!redisProperties.isCacheNullValues()) {config = config.disableCachingNullValues();}if (!redisProperties.isUseKeyPrefix()) {config = config.disableKeyPrefix();}return config;}
}
spring.cache.type=redis#设置超时时间,默认是毫秒spring.cache.redis.time-to-live=3600000#设置Key的前缀,如果指定了前缀,则使用我们定义的前缀,否则使用缓存的名字作为前缀spring.cache.redis.key-prefix=CACHE_spring.cache.redis.use-key-prefix=true#是否缓存空值,防止缓存穿透spring.cache.redis.cache-null-values=true

5.@CacheEvict

/*** 级联更新,保证冗余字段一致* @CacheEvict:失效模式* 1.同时进行多种缓存操作  @Caching* 2.指定删除某个分区下的所有数据 @CacheEvict(value = "category", allEntries = true)* 3.存储同一类型的数据,都可以指定同一分区(缓存默认前缀:分区名)* @param category*/
//    @CachePut  双写模式
//    @CacheEvict(value = "category", allEntries = true)
@Caching(evict = {@CacheEvict(value = "category", key = "'getLevel1Categories'"),@CacheEvict(value = "category", key = "'getCatalogJson'")
})
@Transactional
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category);if(!StringUtils.isEmpty(category.getName())){// 保证冗余数据一致categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());// TODO 其他数据一致
}
}

http://www.ppmy.cn/news/1535785.html

相关文章

Web安全 - 构建全面的业务安全保护防御体系

文章目录 业务安全概述业务安全 vs. 基础安全业务安全的防护业务安全的防护策略1. 用户资源对抗的技术实现与优化2. IP资源对抗的技术实现与优化3. 设备资源对抗的技术实现与优化4. 操作资源对抗的技术实现与优化实际应用场景中的策略 典型场景业务场景 1&#xff1a;新用户注册…

长安UNIZ酷狗音乐闪退死机问题【解决方法】

简介 长安UNIZ车友反馈长安uniz车机经常闪退死机&#xff0c;原因是酷狗音乐的问题。酷狗音乐打开后直接闪退。所以长安汽车官方紧急发布了一个更新包解决这个问题&#xff0c;不得不说&#xff0c;长安汽车还是可以的。下面我把安装包放到文章底部。大家下载到u盘后自行安装到…

五子棋双人对战项目(4)——匹配模块(解读代码)

目录 一、约定前后端交互接口的参数 1、websocket连接路径 2、构造请求、响应对象 二、用户在线状态管理 三、房间管理 1、房间类&#xff1a; 2、房间管理器&#xff1a; 四、匹配器(Matcher) 1、玩家实力划分 2、加入匹配队列&#xff08;add&#xff09; 3、移除…

指针(6)

目录 1. 回调函数是什么&#xff1f; 2. qsort 使⽤举例 使⽤qsort函数排序整型数据 ​编辑3. qsort函数的模拟实现 1. 回调函数是什么&#xff1f; 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&…

高防服务器的优劣势有哪些?

高防服务器是专门用于防御分布式拒绝服务攻击和其他网络攻击所设计的服务器&#xff0c;高防服务器可以用于保护企业网站和应用不会受到网络攻击&#xff0c;但是高防服务器咋某些方面还是有着一些不足的&#xff0c;下面我们就来一起了解一下吧&#xff01; 高防服务器通常都具…

php基础语法

PHP 是一种常用于 Web 开发的服务器端脚本语言&#xff0c;具有易于学习、灵活性强等特点。以下是 PHP 的基础语法详细介绍。 1. PHP 基本语法 PHP 文件扩展名&#xff1a;PHP 文件通常以 .php 作为扩展名。 PHP 标签&#xff1a;PHP 代码通常嵌入到 HTML 中&#xff0c;PHP …

如何使用Redisson的布隆过滤器?

封装布隆过滤器 /*** 创建布隆过滤器** param filterName - 过滤器名称* param expectedInsertions - 预测插入数量* param falsePositiveRate - 误判率* author 付聪* time 2024-09-20 17:24:10*/ <T> RBloomFilter<T> createBloomFilter(String filterName, Lon…

自动驾驶系列—自动驾驶背后的数据通道:通信总线技术详解与应用场景分析

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…