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