当前位置:   article > 正文

SpringBoot整合Redis之@Cacheable、@CachePut、@CacheEvict注解的使用_@cacheable添加统一前缀

@cacheable添加统一前缀

本文操作数据库,使用的是mybatis-plus,关于环境搭建,可查看博文
https://blog.csdn.net/qq_41712271/article/details/115756865

1 添加maven依赖

  1. <!--redis-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-redis</artifactId>
  5. </dependency>
  6. <!--spring cache-->
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-cache</artifactId>
  10. </dependency>
  11. <!--spring cache连接池依赖包-->
  12. <dependency>
  13. <groupId>org.apache.commons</groupId>
  14. <artifactId>commons-pool2</artifactId>
  15. <version>2.6.2</version>
  16. </dependency>

2 配置redis的RedisConfig类

  1. package cn.jiqistudy.redis_1.Config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.PropertyAccessor;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import org.springframework.cache.CacheManager;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.annotation.Primary;
  9. import org.springframework.data.redis.cache.RedisCacheConfiguration;
  10. import org.springframework.data.redis.cache.RedisCacheManager;
  11. import org.springframework.data.redis.cache.RedisCacheWriter;
  12. import org.springframework.data.redis.connection.RedisConnectionFactory;
  13. import org.springframework.data.redis.core.RedisTemplate;
  14. import org.springframework.data.redis.serializer.*;
  15. import java.time.Duration;
  16. /**
  17. * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
  18. * 开启缓存配置,设置序列化
  19. */
  20. @Configuration
  21. @EnableCaching
  22. public class RedisConfig {
  23. @Primary
  24. @Bean
  25. public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
  26. RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
  27. redisCacheConfiguration = redisCacheConfiguration
  28. //设置缓存的默认超时时间:30分钟
  29. .entryTtl(Duration.ofMinutes(30L))
  30. //如果是空值,不缓存
  31. .disableCachingNullValues()
  32. //设置key序列化器
  33. .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
  34. //设置value序列化器
  35. .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()));
  36. return RedisCacheManager
  37. .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
  38. .cacheDefaults(redisCacheConfiguration)
  39. .build();
  40. }
  41. /**
  42. * key序列化器
  43. */
  44. private RedisSerializer<String> keySerializer() {
  45. return new StringRedisSerializer();
  46. }
  47. /**
  48. * value序列化器
  49. */
  50. private RedisSerializer<Object> valueSerializer() {
  51. return new GenericJackson2JsonRedisSerializer();
  52. }
  53. }

3 业务处理编写,缓存操作的核心类

  1. package cn.jiqistudy.redis_1.service;
  2. import cn.jiqistudy.redis_1.mapper.UserMapper;
  3. import cn.jiqistudy.redis_1.pojo.User;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.cache.annotation.CacheConfig;
  8. import org.springframework.cache.annotation.CacheEvict;
  9. import org.springframework.cache.annotation.CachePut;
  10. import org.springframework.cache.annotation.Cacheable;
  11. import org.springframework.stereotype.Service;
  12. import javax.annotation.Resource;
  13. @Service
  14. @CacheConfig(cacheNames = { "user" })
  15. public class UserService {
  16. private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
  17. @Resource
  18. private UserMapper userMapper;
  19. //新增缓存,注意方法的返回值
  20. @Cacheable(key="#id")
  21. public User findUserById(Integer id){
  22. return this.userMapper.selectById(id);
  23. }
  24. //更新缓存,注意方法的返回值
  25. @CachePut(key = "#obj.id")
  26. public User updateUser(User obj){
  27. this.userMapper.updateById(obj);
  28. return this.userMapper.selectById(obj.getId());
  29. }
  30. //删除缓存
  31. @CacheEvict(key = "#id")
  32. public void deleteUser(Integer id){
  33. QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
  34. userQueryWrapper.eq("id",id);
  35. this.userMapper.delete(userQueryWrapper);
  36. }
  37. }

4 测试类编写

  1. import cn.jiqistudy.redis_1.Redis1Application;
  2. import cn.jiqistudy.redis_1.pojo.User;
  3. import cn.jiqistudy.redis_1.service.UserService;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. @RunWith(SpringRunner.class)
  10. @SpringBootTest(classes = Redis1Application.class)
  11. public class Test_7 {
  12. @Autowired
  13. private UserService userService;
  14. //将查询的结果,缓存起来
  15. @Test
  16. public void fangfa1()
  17. {
  18. User userById = userService.findUserById(2);
  19. System.out.println(userById);
  20. }
  21. //同时更新数据库和缓存
  22. @Test
  23. public void fangfa2()
  24. {
  25. User user = new User(2,"李盛霖","男1",15,"地球");
  26. userService.updateUser(user);
  27. }
  28. //同时删除数据库记录和缓存
  29. @Test
  30. public void fangfa3()
  31. {
  32. userService.deleteUser(1);
  33. }
  34. }

详细说明

#### @CacheConfig

@CacheConfig是类级别的注解,统一该类的所有缓存前缀。
``` 
@CacheConfig(cacheNames = { "user" })
public class UserService {
```
以上代码,代表了该类的所有缓存可以都是"user::"为前缀

#### @Cacheable
@Cacheable是方法级别的注解,用于将方法的结果缓存起来
``` 
@Cacheable(key="#id")
public User findUserById(Integer id){
    return this.userMapper.selectByPrimaryKey(id);
}
```
以上方法被调用时,先从缓存中读取数据,如果缓存没有找到数据,再执行方法体,最后把返回值添加到缓存中。

注意:@Cacheable 一般是配合@CacheConfig一起使用的
例如上文的@CacheConfig(cacheNames = { "user" }) 和 @Cacheable(key="#id")一起使用时。
调用方法传入id=100,那redis对应的key=user::100 ,value通过采用GenericJackson2JsonRedisSerializer序列化为json
调用方法传入id=200,那redis对应的key=user::200 ,value通过采用GenericJackson2JsonRedisSerializer序列化为json

#### @CachePut
@CachePut是方法级别的注解,用于更新缓存
``` 
@CachePut(key = "#obj.id")
public User updateUser(User obj){
    this.userMapper.updateByPrimaryKeySelective(obj);
    return this.userMapper.selectByPrimaryKey(obj.getId());
}
```
以上方法被调用时,先执行方法体,然后springcache通过返回值更新缓存,即key = "#obj.id",value=User

#### @CacheEvict(key = "#id")
@CachePut是方法级别的注解,用于删除缓存
``` 
public void deleteUser(Integer id){
    User user=new User();
    user.setId(id);
    user.setDeleted((byte)1);
    this.userMapper.updateByPrimaryKeySelective(user);
}
```
以上方法被调用时,先执行方法体,在通过方法参数删除缓存


### springcache的大坑

1. 对于redis的缓存,springcache只支持String,其他的Hash 、List、set、ZSet都不支持,
   所以对于Hash 、List、set、ZSet只能用RedisTemplate
   
2. 对于多表查询的数据缓存,springcache是不支持的,只支持单表的简单缓存
   对于多表的整体缓存,只能用RedisTemplate。

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

闽ICP备14008679号