在java web开发中,redis的使用已非常频繁了,大规模的使用也延伸了一些问题,例如:我定义了一个redis key name 存放的值为用户昵称,而这时同事定义一个key 也叫name,存放的是商品名字,那么冲突再所难免,为了解决这一问题,合理的设计redis key前缀 成为了迫切的需求。我们一起来看看优雅的设计吧!
采用了简单抽象接口设计
接口------RedisPrefixKey
|
抽象类-----RedisBasePrefixKey
|
实现类 -----RedisUserKey
RedisPrefixKey 接口
public interface RedisPrefixKey {
/**
* redis 过期时间
* @return 过期时间
*/
Long expireSeconds();
/**
* redis key
* @return 键前缀
*/
String getPrefix();
}
接口中定义了两个方法
- 一个是获取redis key 的过期时间
- 一个是获取redis 的key前缀
RedisBasePrefixKey 抽象类
@Data
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;
}
/**
* 构造器
* @param expireSeconds 过期时间
* @param prefix 前缀
*/
public RedisBasePrefixKey(Long expireSeconds,String prefix){
this.expireSeconds = expireSeconds;
this.prefix = prefix;
}
/**
* 获取过期时间
* @return
*/
@Override
public Long expireSeconds() {
return expireSeconds;
}
/**
* 获取Key前缀
* @return
*/
@Override
public String getPrefix() {
String className = getClass().getSimpleName();
return className+":"+prefix+":";
}
}
- @Data lombok 注解 没有插件的自行生成get set
- 最后生成的key是
RedisUserKey:id:1
模块:属性:值 == value
RedisUserKey 实现类(自定义)
public class RedisUserKey extends RedisBasePrefixKey{
public static final String USER_KEY_ID = "id";
public static final String USER_KEY_TOKEN = "token";
/**
* 用户key
*/
public static RedisUserKey getUserId = new RedisUserKey(USER_KEY_ID);
public static RedisUserKey getUserToken = new RedisUserKey(3600*24L,USER_KEY_TOKEN);
private RedisUserKey(String prefix) {
super(prefix);
}
private RedisUserKey(Long expireSeconds, String prefix) {
super(expireSeconds, prefix);
}
}
- 私有化构造器防止外面new创建
redisService 需要改造一下set get
/**
* 普通缓存放入
*
* @param prefix 键前缀
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(RedisPrefixKey prefix,String key, Object value) {
try {
Long expire = prefix.expireSeconds();
ValueOperations ops = redisTemplate.opsForValue();
if(expire <= 0){
ops.set(prefix.getPrefix()+key, value);
}else{
ops.set(prefix.getPrefix()+key, value,expire,TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存获取
* @param prefix 键前缀
* @param key 键
* @return 值
*/
public Object get(RedisPrefixKey prefix,String key) {
if(key==null || key.length()<=0){
return null;
}
return redisTemplate.opsForValue().get(prefix.getPrefix()+key);
}
- redisTemplate 详见spring整合redis
具体使用
//设置用户缓存
User user = userService.queryById(1);
redisService.set(UserKey.getUserId,user.getId()+"",user);
User u = (User)redisService.get(UserKey.getUserId,user.getId()+"");
System.out.println(u.toString());
//设置用户session
String token = UUID.randomUUID().toString().replace("-","");
redisService.set(UserKey.getUserToken,token,user);
u = (User)redisService.get(UserKey.getUserToken,token);
System.out.println(u.toString());