Redis key前缀的设计与使用

本文介绍了一种优雅地设计Redis Key前缀的方法,通过模板方法模式,利用接口RedisPrefixKey、抽象类RedisBasePrefixKey和自定义实现类UserKey,有效避免了Key冲突,提升了缓存管理效率。

在Java web开发中,redis的使用已非常频繁了,大规模的使用也延伸了一些问题,例如:我定义了一个redis key name 存放的值为用户昵称,而这时同事定义一个key 也叫name,存放的是商品名字,那么冲突再所难免,为了解决这一问题,合理的设计redis key前缀 成为了迫切的需求。我们一起来看看优雅的设计吧!

采用模板方法模式进行设计前缀空间

接口------RedisPrefixKey
|
抽象类-----RedisBasePrefixKey
|
实现类 -----UserKey

RedisPrefixKey 接口

public interface RedisPrefixKey {
    /**
     * redis 过期时间
     * @return 过期时间
     */
    Long getExpireSeconds();

    /**
     * redis key
     * @return 键前缀
     */
    String getPrefix();
}

接口中定义了两个方法

  • 获取redis key 的过期时间 getExpireSeconds()
  • 获取redis 的key前缀getPrefix()

RedisBasePrefixKey 抽象类

@Setter
@AllArgsConstructor
public abstract class RedisBasePrefixKey implements RedisPrefixKey {
    /**
     * 过期时间
     */
    private Long expireSeconds;
    /**
     * redis key前缀
     */
    private String prefix;

    /**
     * 构造器
     * expireSeconds 为零默认为永不过期
     *
     * @param prefix 前缀
     */
    public RedisBasePrefixKey(String prefix) {
        this.prefix = prefix;
        this.expireSeconds = 0L;
    }

    /**
     * 获取过期时间
     *
     * @return
     */
    @Override
    public Long getExpireSeconds() {
        return expireSeconds;
    }

    /**
     * 获取Key前缀
     *
     * @return
     */
    @Override
    public String getPrefix() {
        String className = getClass().getSimpleName();
        return className.concat(":").concat(prefix).concat(":");
    }
}

UserKey 实现类(自定义)

私有化构造器防止外面new创建

public class UserKey extends RedisBasePrefixKey{

    private UserKey(Long expireSeconds, String prefix) {
        super(expireSeconds, prefix);
    }

    private UserKey(String prefix){
        super(prefix);
    }

    public static final String USER_KEY_ID = "uid";
    /**
     * 用户key
     */
    public static UserKey userId = new UserKey(USER_KEY_ID);

}

最后生成的key是 UserKey:uid:1 模块:属性:值 == value

改造RedisUtil工具类的方法

/**
 *
 * @param prefix 键前缀
 * @param key 键
 * @param value 值
 * @return true成功 false 失败
 */
public boolean set(RedisPrefixKey prefix, String key, Object value) {
    try {
        long time = prefix.getExpireSeconds();
        if (time > 0) {
            redisTemplate.opsForValue().set(prefix.getPrefix().concat(key), value, time, TimeUnit.SECONDS);
        } else {
            set(prefix.getPrefix().concat(key), value);
        }
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

/**
 * 普通缓存放入
 *
 * @param key   键
 * @param value 值
 * @return true成功 false失败
 */
public boolean set(String key, Object value) {
    try {
        redisTemplate.opsForValue().set(key, value);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

/**
 * 普通缓存获取
 *
 * @param key 键
 * @return 值
 */
public Object get(RedisPrefixKey prefix, String key) {
    return key == null ? null : redisTemplate.opsForValue().get(prefix.getPrefix().concat(key));
}

具体使用

//设置用户缓存
User user = userService.queryById(1);
redisUtil.set(UserKey.userId,user.getId()+"",user);
User u = (User)redisUtil.get(UserKey.getUserId,user.getId()+"");
System.out.println(u.toString());

参考

springboot-No4-3 集成redis 下 redis的key前缀空间引入
redis key前缀的设计与使用

在 Java 项目中使用 **Redis Key 前缀**,并通过 **Nacos 配置中心**进行统一管理,是一种非常常见的微服务配置实践。这种方式可以实现: - 配置集中管理(如 key 前缀、过期时间等) - 动态更新配置(配合 `@RefreshScope`) - 多环境支持(dev、test、prod) --- ## ✅ 一、整体流程 1. 在 **Nacos 控制台**中配置 Redis Key 前缀(如 `chatbot:model:`) 2. 在 Spring Boot 项目中通过 `@Value` 或 `@ConfigurationProperties` 读取该配置 3. 在 Redis 操作中拼接完整的 key --- ## ✅ 二、Nacos 配置示例 在 Nacos 控制台添加如下配置(Data ID 为 `application.yml`): ```yaml redis: key: chatbot-model-prefix: "chatbot:model:" ``` - **Group**: `DEFAULT_GROUP` - **Data ID**: `application.yml` --- ## ✅ 三、Spring Boot 项目配置 ### 1. 添加依赖(Maven) ```xml <!-- Nacos 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2022.0.0.0</version> </dependency> <!-- Spring Boot 配置处理器(可选) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> ``` ### 2. 配置 `bootstrap.yml` ```yaml spring: application: name: your-service-name cloud: nacos: config: server-addr: 127.0.0.1:8848 extension-configs: - data-id: application.yml group: DEFAULT_GROUP refresh: true ``` --- ## ✅ 四、Java 代码中使用 Redis Key 前缀 ### ✅ 方法一:使用 `@Value` 注入配置 ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class RedisKeyManager { @Value("${redis.key.chatbot-model-prefix}") private String chatbotModelPrefix; public String getChatbotModelKey(String modelId) { return chatbotModelPrefix + modelId; } } ``` ### ✅ 方法二:使用 `@ConfigurationProperties`(推荐用于多配置) ```java import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "redis.key") public class RedisKeyProperties { private String chatbotModelPrefix; public String getChatbotModelPrefix() { return chatbotModelPrefix; } public void setChatbotModelPrefix(String chatbotModelPrefix) { this.chatbotModelPrefix = chatbotModelPrefix; } } ``` ### ✅ 在 Redis 操作中使用 Key 前缀 ```java import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class ChatbotRedisService { @Resource private RedisKeyProperties redisKeyProperties; @Resource private RedisTemplate<String, Object> redisTemplate; public void saveModelData(String modelId, Object data) { String key = redisKeyProperties.getChatbotModelPrefix() + modelId; redisTemplate.opsForValue().set(key, data); } public Object getModelData(String modelId) { String key = redisKeyProperties.getChatbotModelPrefix() + modelId; return redisTemplate.opsForValue().get(key); } } ``` --- ## ✅ 五、动态刷新配置(可选) 如果你希望配置更新后自动刷新 Redis Key 前缀,可以加上 `@RefreshScope` 注解: ```java import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component; @Component @RefreshScope public class RedisKeyManager { ... } ``` --- ## ✅ 六、效果演示 假设你将 `modelId = "1001"` 传入: ```java String key = redisKeyProperties.getChatbotModelPrefix() + "1001"; // key = "chatbot:model:1001" ``` 你就可以用这个 key 来操作 Redis: ```java redisTemplate.opsForValue().set("chatbot:model:1001", modelData); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值