Redis 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前綴的設計與使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章