Spring Boot-Redis教程

Redis 是一种开源内存数据结构存储,可用作数据库、缓存和消息代理。将 Redis 与 Spring Boot 集成提供了一种在应用程序中利用 Redis 的简单而有效的方法。下面总结一下如何将Redis与Spring Boot集成:

Docker 文件
这是基本的 docker-compose redis 配置

services:
    redis:
    image: redis:latest
    restart: always
    ports:
      - "6379:6379"
    environment:
      - REDIS_PASSWORD=my-password
      - REDIS_PORT=6379
      - REDIS_DATABASES=16

Maven 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

应用程序yml文件

spring:
  cache:
    type: redis
    redis:
      host: localhost
      port: 6379

cache:
  config:
    entryTtl: 60
    jwtToken:
      entryTtl: 30

在application yml文件中,定义了缓存类型和redis主机、端口信息。

Redis 配置类

@Configuration
@EnableCaching
@Slf4j
public class RedisConfig {

    @Value("${spring.cache.redis.host}")
    private String redisHost;

    @Value("${spring.cache.redis.port}")
    private int redisPort;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHost, redisPort);
        configuration.setPassword("my-password");
        log.info("Connected to : {} {}", redisHost, redisPort);

        return new LettuceConnectionFactory(configuration);
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        return RedisCacheManager.create(connectionFactory);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(){
        final RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new GenericToStringSerializer<Object>(Object.class));
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

使用缓存注释
要在应用程序中启用缓存,您可以使用注释,然后使用、和@EnableCaching注释应缓存的方法@Cacheable@CachePut@CacheEvict

@GetMapping("/product/{id}")  
@Cacheable(value = "product", key = "#id")
public Product getProductById(@PathVariable long id) {...}

1. @Cacheable用于从数据库中获取数据,并将其存储在缓存中。以后调用时,该方法会直接检索缓存的值,无需再次执行该方法。
该value属性建立一个具有特定名称的缓存,同时该key属性允许使用 Spring 表达式语言动态计算密钥。因此,方法结果存储在“product”缓存中,其中相应的“product_id”作为唯一键。这种方法通过将每个结果与不同的键相关联来优化缓存。

2、 @CachePut用于当源数据库有更新时更新缓存中的数据。

@PutMapping("/product/{id}")
@CachePut(cacheNames = "product", key = "#id")
public Product editProduct(@PathVariable long id, @RequestBody Product product) {...}

3 . @CacheEvict用于从缓存中删除陈旧或未使用的数据。

@DeleteMapping("/product/{id}")
@CacheEvict(cacheNames = "product", key = "#id", beforeInvocation = true)
public String removeProductById(@PathVariable long id) {...}

我们使用cacheName和key从缓存中删除特定数据。 beforeIncation 属性允许我们控制逐出过程,使我们能够选择逐出是在方法执行之前还是之后发生。

@DeleteMapping("/product/{id}")
@CacheEvict(cacheNames = "product", allEntries = true)
public String removeProductById(@PathVariable long id) {...}

或者,也可以通过将 allEntries 属性设置为 true 来删除给定缓存的所有数据。该注释允许我们通过提供多个值作为cacheName来清除多个缓存的数据。

4 . @Caching用于同一方法上的多个嵌套缓存。

@PutMapping("/{id}")
@Caching(
     evict = {@CacheEvict(value = "productList", allEntries = true)},
     put = {@CachePut(value = "product", key = "#id")}
)
public Product editProduct(@PathVariable long id, @RequestBody Product product) {...}

由于 Java 不允许为一个方法声明相同类型的多个注释,因此这样做会产生编译错误。我们可以将不同的注释分组到缓存中,如图所示。

5 . @CacheConfig用于集中配置。

@CacheConfig(cacheNames = "product")
public class ProductController {...}

使用 RedisTemplate
您可以使用RedisTemplate与Redis交互。例如,将数据保存到Redis中:

@Autowired
private RedisTemplate<String, Object> redisTemplate;

public void saveData(String key, Object data) {
    redisTemplate.opsForValue().set(key, data);
}

从Redis中检索数据

public Object getData(String key) {
    return redisTemplate.opsForValue().get(key);
}

Redis 模板的示例服务类

@Service
public class CacheTokenService {

    private final StringRedisTemplate stringRedisTemplate;
    private final RedisTemplate<String, Object> redisTemplate;

    public CacheTokenService(StringRedisTemplate stringRedisTemplate, RedisTemplate<String, Object> redisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.redisTemplate = redisTemplate;
    }

    public void saveData(String key, Object data) {
        redisTemplate.opsForValue().set(key, data);
    }

    public Object getData(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    public void cacheToken(String username, String token) {
        stringRedisTemplate
        .opsForValue()
        .set("token:" + username, token, Duration.ofMinutes(60));
    }

    public String getCachedToken(String username) {
        // Retrieve the token from Redis cache
        return stringRedisTemplate
        .opsForValue()
        .get("token:" + username);
    }

}

Redis 图形用户界面:RedisInsight
下载链接:https://redis.io/insight/