Spring Data Redis使用方式

时间:2024-11-17 10:04:32

使用步骤:

1.导入Spring Data Redis坐标(pom.xml)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>
坐标1:redis依赖
坐标2:用于解决redis转换java8新类型报错的问题

2.配置Redis数据源(application.yml文件)

spring:
  redis:
    host: localhost # redis服务器地址
    port: 6379 # redis端口号
    password: # redis密码 如果没有密码可以不写
    database: 0 # redis提供了16个数据库,默认为0

3.编写配置类、创建Redis Template对象

package com.sky.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Random;


/**
 * Redis配置类,用于配置RedisTemplate以支持自定义的序列化和反序列化。
 * 通过自定义序列化器,可以将复杂的Java对象序列化为JSON格式存储到Redis中,并在读取时反序列化为Java对象。
 */
@Configuration
@EnableCaching
@Slf4j
public class RedisConfig {
    /**
     * 配置RedisTemplate以使用自定义序列化器。
     *
     * @param redisConnectionFactory Redis连接工厂,用于创建Redis连接
     * @return 配置好的RedisTemplate实例
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        log.info("开始创建RedisTemplate实例...");
        // 创建RedisTemplate实例
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();

        // 设置Redis连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 使用Jackson2JsonRedisSerializer替换默认的序列化方式,以便将对象序列化为JSON格式存储在Redis中
        Jackson2JsonRedisSerializer jsonRedisSerializer =
                new Jackson2JsonRedisSerializer(Object.class);
        // 配置ObjectMapper以解决查询缓存转换异常
        ObjectMapper om = new ObjectMapper();
        // 支持Java8的时间类型
        om.registerModule(new JavaTimeModule());
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(om);

        // 设置RedisTemplate的value序列化器为自定义的JSON序列化器
        // 这样可以将复杂的Java对象序列化为JSON格式存储到Redis中
        redisTemplate.setValueSerializer(jsonRedisSerializer);

        // 设置RedisTemplate的key序列化器为StringRedisSerializer
        // 这样可以将字符串类型的键存储到Redis中
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        // 初始化RedisTemplate,确保所有属性设置正确
        redisTemplate.afterPropertiesSet();

        // 返回配置好的RedisTemplate实例
        return redisTemplate;
    }


    /**
     * 创建自定义的KeyGenerator,用于生成缓存的键。
     *
     * @return 自定义的KeyGenerator实例
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                // 格式化缓存key字符串
                StringBuilder sb = new StringBuilder();
                // 追加类名
                sb.append(target.getClass().getName());
                // 追加方法名
                sb.append(method.getName());
                // 遍历参数并追加
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 配置CacheManager以使用自定义的序列化和反序列化。
     *
     * @param factory Redis连接工厂,用于创建Redis连接
     * @return 配置好的CacheManager实例
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 创建Redis序列化对象
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        // 创建Jackson的序列化对象
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        // 支持Java8的时间类型
        om.registerModule(new JavaTimeModule());
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题)
        RedisCacheConfiguration configuration =
                RedisCacheConfiguration.defaultCacheConfig()
                        // 设置缓存过期时间
                        .entryTtl(Duration.ofSeconds(new Random().nextInt(+0*60*60*24+new Random().nextInt(+60*60*24))))
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.
                                fromSerializer(redisSerializer))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.
                                fromSerializer(jackson2JsonRedisSerializer))
                        .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(configuration).build();
        return cacheManager;
    }
}

4.手动清除redis中的缓存

 /**
     * 统一清理所有的key
     * 
     * @param pattern 缓存key的模式,用于匹配需要清理的缓存
     */
    private void clearCache(String pattern) {
        // 记录清理缓存的日志,提高可追踪性
        log.info("清理缓存的key:{}", pattern);
        
        // 使用RedisTemplate查找所有匹配给定模式的key
        Set keys = redisTemplate.keys(pattern);
        
        // 删除所有匹配的key,释放缓存空间
        redisTemplate.delete(keys);
    }