微服务实战——SpringCache 整合 Redis

server/2024/10/18 1:36:04/

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/server/127907.html

相关文章

codetop标签动态规划大全C++讲解(三)!!动态规划刷穿地心!!学吐了家人们o(╥﹏╥)o

每天复习一篇&#xff0c;只有十题左右 1.买卖股票的最佳时机2.买卖股票的最佳时机含手续费3.买卖股票的最佳时机III4.买卖股票的最佳时机IV5.打家劫舍6.打家劫舍II7.不同路径8.不同路径II9.最小路径和10.三角形的最小路径和11.两个字符串的删除操作12.编辑距离13.一和零 1.买卖…

基于Hive和Hadoop的电商消费分析系统

本项目是一个基于大数据技术的电商消费分析系统&#xff0c;旨在为用户提供全面的电商消费信息和深入的消费行为分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 S…

使用Node.js的readline模块逐行读取并解析大文件

在Node.js环境中处理大文件是一个常见的需求&#xff0c;尤其是在处理日志文件、数据库导出、或任何形式的大规模文本数据时。由于Node.js是基于事件循环和非阻塞I/O的&#xff0c;它非常适合处理这类任务。然而&#xff0c;直接将整个文件内容加载到内存中可能会导致内存溢出&…

Leetcode—139. 单词拆分【中等】

2024每日刷题&#xff08;173&#xff09; Leetcode—139. 单词拆分 dp实现代码 class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {int n s.size();unordered_set<string> ust(wordDict.begin(), wordDict.end());vector<b…

报错Invalid HADOOP_HDFS_HOME

使用env命令查看已有环境变量 果然多了一个变量&#xff0c;因为不需要&#xff0c;所以删除&#xff0c;再次使用env命令查看&#xff0c;无此变量 再输入hadoop,显示正确

八大排序--01冒泡排序

假设有一组数据 arr[]{2&#xff0c;0&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;7} 方法&#xff1a;开辟两个指针&#xff0c;指向如图&#xff0c;前后两两进行比较&#xff0c;大数据向后冒泡传递&#xff0c;小数据换到前面。 一次冒泡后&#xff0c;数组中最大…

最新BurpSuite2024.9专业中英文开箱即用版下载

1、工具介绍 本版本更新介绍 此版本对 Burp Intruder 进行了重大改进&#xff0c;包括自定义 Bambda HTTP 匹配和替换规则以及对扫描 SOAP 端点的支持。我们还进行了其他改进和错误修复。 Burp Intruder 的精简布局我们对 Burp Intruder 进行了重大升级。现在&#xff0c;您可…

计算机毕业设计Python+Tensorflow股票推荐系统 股票预测系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI

《PythonTensorflow股票推荐与预测系统》开题报告 一、研究背景与意义 在信息技术高速发展的今天&#xff0c;金融市场日益复杂&#xff0c;投资者面临着越来越多的选择和挑战。股票作为金融市场的重要组成部分&#xff0c;其价格波动受到多种因素的影响&#xff0c;包括宏观…