当前位置:   article > 正文

SpringBoot使用Redis作为缓存器缓存数据的操作步骤以及避坑方案_springboot如何缓存一些数据

springboot如何缓存一些数据

1.非注解式实现

2.1使用之前要明确使用的业务场景

例如我们在登录时,可以让redis缓存验证码,又如在分类下显示菜品数据时,我们可以对分类和菜品进行缓存数据等等。

2.2导入Redis相关依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>

2.3在使用的controller层导入RedisTemplate

例如:

说明一下:这里为什么使用@Resource注解而不使用@Autowired注解。

Spring框架中,@Resource和@Autowired都是用来完成依赖注入的注解,它们可以将其他组件或者资源注入到当前的类中。在Spring框架中,@Resource和@Autowired都是用来完成依赖注入的注解,它们可以将其他组件或者资源注入到当前的类中

@Resource是Java提供的一个通用注解,而@Autowired是Spring框架提供的注解。@Resource注解默认按照名称进行装配,通过name属性指定注入的目标对象名称。而@Autowired默认按照类型进行装配,它会自动根据类型选择合适的对象进行注入。另外,@Autowired注解可以配合@Qualifier注解一起使用,通过指定具体的bean名称来完成注入。

其次,@Resource可以用于注入任意的bean,包括其他类、接口、甚至是字符串等类型的资源而@Autowired注解主要用于注入其他的bean对象

此外,@Resource注解可以标注在字段、setter方法、构造方法和方法上,而@Autowired注解通常标注在字段和构造方法上。

在实践中,选择使用@Resource还是@Autowired取决于具体的需求和场景。如果需要按照名称进行注入,或者需要注入的对象是一个非Spring托管的对象,可以使用@Resource注解。如果只是简单的注入Spring托管的对象,并且希望按照类型自动选择合适的bean进行注入,可以使用@Autowired注解。

需要注意的是,@Resource和@Autowired注解都需要对应的类进行配置,以让Spring框架知道需要进行依赖注入的对象。

通过上面的说明,其实我们自己内心里已经有答案,孰强孰弱啦。

 2.4此时,我们要配置Redis

2.4.1配置application.yml

2.4.2编写RedisConfig配置类

由于Redis是一个内存数据库,它将数据存储在内存中,因此需要将数据序列化为字节流进行存储。在将数据存入Redis或从Redis中取出数据时,需要进行序列化和反序列化的操作。

  1. @Configuration
  2. public class RedisConfig extends CachingConfigurerSupport {
  3. /**
  4. * 自定义RedisTemplate
  5. * 设置Redis序列化方式,默认使用的是JDKSerializer的序列化方式,效率低,所以这里设置使用FastJsonRedisSerializer
  6. */
  7. @Bean
  8. @SuppressWarnings(value = {"unchecked", "rawtypes"})
  9. public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
  10. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  11. // 设置redis连接(LettuceConnectionFactory实现了RedisConnectionFactory)
  12. redisTemplate.setConnectionFactory(connectionFactory);
  13. FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
  14. // key设置StringRedisSerializer序列化
  15. redisTemplate.setKeySerializer(new StringRedisSerializer());
  16. // Hash key设置序列化
  17. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  18. return redisTemplate;
  19. }
  20. }

可以参考一下,或许有更好的,大家可以借鉴一下。

2.5使用缓存(验证码为例)

 此时我们可以测试一下,在此之前呢,怎么看缓存数据是一个问题,所以,安排一下Redis的可视化工具:

链接:https://pan.baidu.com/s/1OUNza9ea9fQepXqNTeTq-g 
提取码:frpd

2.6测试

 

这只是一个简单的应用,然后我们再来一个其他的案例:缓存菜品数据

业务场景如下:

每个分类,比如湘菜,川菜,每次点击都需要再次重新查询数据库,不仅压力更大而且造成资源浪费,我们可以把这些查询的数据,按菜品分类给存入redis中,设置其30分钟生存周期,这样再次点击查看,就不会再查询数据库,直接从redis中获取数据,降低服务器压力也避免资源浪费。

缓存逻辑:

我们先动态构造唯一key值,然后根据key来获取value,接下来判断value是否为空,若不为空则表示redis中有该分类下的数据,直接返回;若为空则需要去数据库查询数据,然后再把查询的数据放入redis缓存中,下次再查询直接走redis缓存,不用再次查询数据库。

这个就不再演示了,到这里我们就可以明显觉得,代码量上来了,这只是一个查询都这样,再细想一下,这个查询会不会因为这个缓存出现问题,比如说我们新增了菜品,修改了菜品,删除了菜品,这个缓存区是不是得动一动,那这个重复的代码多不多,显而易见。

2.使用Spring Cache框架优化Redis缓存的过程

简单介绍一下这一位大咖:Spring Cache框架是Spring框架提供的一套基于注解的缓存解决方案,它在应用程序中简化了缓存操作的管理和使用。

Spring Cache框架的核心思想是通过在方法上添加缓存注解,来实现自动缓存的功能。它提供了一些常用的注解,如:

  • @Cacheable:标注在方法上,表示该方法的返回结果可以被缓存,当方法被调用时,会首先检查缓存,如果缓存命中,则直接返回缓存中的结果,不再执行方法体中的逻辑。
  • @CachePut:标注在方法上,表示该方法的返回结果需要更新缓存,每次方法被调用后,都会将返回结果更新到缓存中。
  • @CacheEvict:标注在方法上,表示该方法会清除缓存中的数据,可以用于在更新或删除数据时清除相应的缓存。

2.1导入Spring Cache依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>

2.2启动类上加上注解开启缓存

 2.3返回结果类实现序列化接口

 2.4改造上一个案例的代码

不用意外,就是什么关于redis的什么都不剩了 ,我们只需要再控制层的接口上加上一个注解,就完事了。

 2.5测试

测试后即会在redis中产生一个这样的目录结构

对照接口上的注解再理解一下你就会明白其中的意思了。

这个时候你和非注解方式对比你会发现一个问题,过期时间去哪啦,没法设置过期时间了!

3.再次优化Spring Cache使用 

使用@Cacheable时,无法直接设置过期时间,需要自定义RedisCacheManager来实现ttl设置。

3.1编写TtlRedisCacheManager类来获取注解@Cacheable的参数

  1. public class TtlRedisCacheManager extends RedisCacheManager {
  2. public TtlRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
  3. super(cacheWriter, defaultCacheConfiguration);
  4. }
  5. @Override
  6. protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
  7. String[] cells = StringUtils.delimitedListToStringArray(name, "=");
  8. name = cells[0];
  9. if (cells.length > 1) {
  10. long ttl = Long.parseLong(cells[1]);
  11. // 根据传参设置缓存失效时间,默认单位是秒
  12. cacheConfig = cacheConfig.entryTtl(Duration.ofMinutes(ttl));
  13. }
  14. return super.createRedisCache(name, cacheConfig);
  15. }
  16. }

3.2修改RedisConfig配置类

  1. @Configuration
  2. public class RedisConfig extends CachingConfigurerSupport {
  3. /**
  4. * 自定义RedisTemplate
  5. * 设置Redis序列化方式,默认使用的是JDKSerializer的序列化方式,效率低,所以这里设置使用FastJsonRedisSerializer
  6. */
  7. @Bean
  8. @SuppressWarnings(value = {"unchecked", "rawtypes"})
  9. public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
  10. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  11. // 设置redis连接(LettuceConnectionFactory实现了RedisConnectionFactory)
  12. redisTemplate.setConnectionFactory(connectionFactory);
  13. FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
  14. // key设置StringRedisSerializer序列化
  15. redisTemplate.setKeySerializer(new StringRedisSerializer());
  16. // Hash key设置序列化
  17. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  18. return redisTemplate;
  19. }
  20. /**
  21. * 实例化自定义的缓存管理器
  22. */
  23. @Bean
  24. @Primary
  25. @SuppressWarnings(value = {"unchecked", "rawtypes"})
  26. public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
  27. RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisTemplate.getConnectionFactory()));
  28. RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
  29. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
  30. return new TtlRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
  31. }
  32. }

注意:项目中已配置了RedisCacheManager需要在原配置的bean上添加注解@Primary,以免造成干扰

3.3修改controller层数据接口的注解

根据你在RedisCacheManager中设置的什么格式来填写value即可。

即完成对Redis缓存数据的使用。有什么问题还请留言。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/164553
推荐阅读
相关标签
  

闽ICP备14008679号