RedisTemplate重写的一些模板

1.为什么要重写RedisTemplate

我们知道SpringBoot官方给出了2种实例化方式 ,分别是 RedisTemplate<Object,Object>RedisTemplate<String,String>

这两种或多或少都有一些问题;

1.第一种 对key所采用的序列化方式是JdkSerializationRedisSerializer

由此种方式序列化的key 在存入Redis数据库时会被转为16进制同时具有类型前缀(非常复杂难看懂) ,这样想要拿取key对应的value 还要先算出此key的值,所以不采用该种。

2.第二种 要求value值类型也为String,导致数据操作步骤繁琐,较为影响运行效率。所以我们一般重写一RedisTemplate<String,Object>

这样更切合业务并且代码操作更加简单,SpringBoot官方的设置也是当你手动注入一个RedisTemplate的Bean时,优先使用你手动注入的RedisTemplate。(如使用第二种的话,我需要手动将对象数据 进行json转化,影响代码效率,存储起来也非常麻烦)

2.实例

java 复制代码
package com.wyh.gateway.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.StringRedisSerializer;

/**
 * Redis的config处理
 *
 * @author: chopin
 * @create: 2023/12/2 23:00
 */
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //1.redisTemplate 是一个key-value存储的模板,它可以操作hash、list、set、zset等数据结构,但是默认序列化是乱码的
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        StringRedisSerializer redisSerializer = new StringRedisSerializer();
        //2.设置了 RedisConnectionFactory 对象,它是 Redis 客户端的连接工厂,它可以创建和管理 Redis 客户端连接。
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //3.设置了 RedisTemplate 的 key 序列化器为 StringRedisSerializer 对象,它可以将字符串对象转换为 Redis 的键
        redisTemplate.setKeySerializer(redisSerializer);
        //4.设置了 RedisTemplate 的 hash key 序列化器为 StringRedisSerializer 对象,它可以将字符串对象转换为 Redis 的哈希键
        redisTemplate.setHashKeySerializer(redisSerializer);
        //5.设置了 RedisTemplate 的 value 序列化器为 jackson2JsonRedisSerializer 对象,它可以将 Java 对象序列化为 JSON 字符串并将其存储在 Redis 中
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
        return redisTemplate;
    }

    public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
        // 创建一个 Jackson2JsonRedisSerializer 对象,其泛型类型为 Object
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // 创建一个 ObjectMapper 对象
        ObjectMapper objectMapper = new ObjectMapper();
        // 允许所有属性可见,包括私有属性
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 禁用对未知属性的失败
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 启用默认的类型,即非终态类型
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        // 将 ObjectMapper 对象设置为 Jackson2JsonRedisSerializer 对象
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        // 返回 Jackson2JsonRedisSerializer 对象
        return jackson2JsonRedisSerializer;
    }
}

RedisUtils

java 复制代码
package com.wyh.gateway.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Redis工具类
 *
 * @author: chopin
 * @create: 2023/12/2 23:10
 */
@Component
@Slf4j
public class RedisUtil {

    @Resource
    private RedisTemplate redisTemplate;

    private static final String CACHE_KEY_SEPARATOR = ".";

    /**
     * 构建缓存key
     */
    public String buildKey(String... strObjs) {
        return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR));
    }

    /**
     * 是否存在key
     */
    public boolean exist(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 删除key
     */
    public boolean del(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * set(不带过期)
     */
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * set(带过期)
     */
    public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
    }

    /**
     * 获取string类型缓存
     */
    public String get(String key) {
        return (String) redisTemplate.opsForValue().get(key);
    }

    public Boolean zAdd(String key, String value, Long score) {
        return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score)));
    }

    public Long countZset(String key) {
        return redisTemplate.opsForZSet().size(key);
    }

    public Set<String> rangeZset(String key, long start, long end) {
        return redisTemplate.opsForZSet().range(key, start, end);
    }

    public Long removeZset(String key, Object value) {
        return redisTemplate.opsForZSet().remove(key, value);
    }

    public void removeZsetList(String key, Set<String> value) {
        value.stream().forEach((val) -> redisTemplate.opsForZSet().remove(key, val));
    }

    public Double score(String key, Object value) {
        return redisTemplate.opsForZSet().score(key, value);
    }

    public Set<String> rangeByScore(String key, long start, long end) {
        return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end)));
    }

    public Object addScore(String key, Object obj, double score) {
        return redisTemplate.opsForZSet().incrementScore(key, obj, score);
    }

    public Object rank(String key, Object obj) {
        return redisTemplate.opsForZSet().rank(key, obj);
    }


}
相关推荐
程序员无隅3 小时前
Coding Agent 为什么压缩上下文后还能继续工作?上下文模块设计拆解
java·开发语言·数据库
Python+993 小时前
Java 枚举类(Enum)详解:从基础到高级应用
java·开发语言·python
二炮手亮子3 小时前
浅记java线程池
java·开发语言
zmzb01033 小时前
C++课后习题训练记录Day157
开发语言·c++
dunge20263 小时前
2026年7月最新ChatGPT Plus / Pro 与 Codex:当 AI Agent 最新5.6版本来袭,必须理解事务、幂等与补偿
开发语言·人工智能·python
爱吃牛肉的大老虎5 小时前
rust基础之环境搭建
java·开发语言·rust
openKylin5 小时前
与全球技术演进同频,openKylin 3.0从C迈向Rust
c语言·开发语言·rust·开源·开放原子·openkylin
疯狂打码的少年6 小时前
【软件工程】结构化设计:模块独立性与耦合内聚
java·开发语言·笔记·软件工程
程高兴6 小时前
PMSM基于在线转动惯量辩识的滑模负载转矩观测器MATLAB-SIMULINK仿真模型
开发语言·matlab
kisloy7 小时前
【python零基础教程第24讲】代码规范与质量管控
开发语言·python