目标:操作redis map对象,像操作本地HashMap一样的体验
使用:
RedisMap<String, ServiceEntity> serviceInfoCache=new RedisMap<String, ServiceEntity>(stringRedisTemplate,"service_info") {};
serviceInfoCache.put("key1",new ServiceEntity());
ServiceEntity entity = serviceInfoCache.get("key1");
定义接口:
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* create by zzb
* 2018/10/11
*/
public interface CatcherMap<K,V> {
boolean isEmpty();
boolean containsKey(K key);
void put(K key, V value);
void putAll(Map<K, V> map);
boolean remove(K... keys);
V get(K key);
List<V> multiGet(Collection<K> keys);
Collection<V> values();
int size();
Map<K,V> entries();
}
定义实现类:
import com.alibaba.fastjson.JSONObject;
import com.google.common.reflect.TypeToken;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**必须用new RedisMap<K,V>(){}才能创建,只有这样才能拿到泛型的类型
* create by zzb
* 2018/10/11
*/
public abstract class RedisMap<K,V> implements CatcherMap<K,V> {
protected StringRedisTemplate redisEnv;
private String preKey;
private Type keyType;
private Type valueType;
public RedisMap(StringRedisTemplate redisEnv, String preKey) {
this.redisEnv = redisEnv;
this.preKey = preKey;
getGenType();
}
public RedisMap(StringRedisTemplate redisEnv, String preKey, Type valueType) {
this(redisEnv,preKey);
this.valueType = valueType;
}
@Override
public Map<K,V> entries(){
Map<Object,Object> map = redisEnv.opsForHash().entries(preKey);
Map<K,V> result = new HashMap<>(map.size()*2);
map.forEach((keyObject,valueObject) ->{
V value = parseValue(valueObject);
K key = parseKey(keyObject);
result.put(key,value);
});
return result;
}
@Override
public boolean containsKey(K key) {
return redisEnv.opsForHash().hasKey(preKey,serializeObject(key));
}
@Override
public void put(K key, V value) {
if(key == null || value==null) return;
redisEnv.opsForHash().put(preKey,serializeObject(key),serializeObject(value));
}
public void putAll(Map<K,V> map){
if(map !=null&&map.size() >0){
Map<String,String> kvMap = new HashMap<>(map.size());
map.forEach((key,val)->kvMap.put(serializeObject(key),serializeObject(val)));
redisEnv.opsForHash().putAll(preKey,kvMap);
}
}
@Override
public boolean remove(K... keys) {
int size = keys.length;
Object[] hasKeys = new Object[size];
for(int i=0;i<size;i++){
hasKeys[i]=serializeObject(keys[i]);
}
return redisEnv.opsForHash().delete(preKey,hasKeys)>0;
}
@Override
public V get(K key) {
Object valueObject = redisEnv.opsForHash().get(preKey,serializeObject(key));
return parseValue(valueObject);
}
@Override
public List<V> multiGet(Collection<K> keys){
if(keys==null || keys.size()==0){
return new ArrayList<>(1);
}
List<String> keyObjectList = new ArrayList<>(keys.size());
keys.forEach(key->keyObjectList.add(serializeObject(key)));
HashOperations<String,String,String> options = redisEnv.opsForHash();
List<String> valueObjectList = options.multiGet(preKey,keyObjectList);
List<V> result = new ArrayList<>(valueObjectList.size());
valueObjectList.forEach(item->result.add(parseValue(item)));
return result;
}
@Override
public Collection<V> values() {
List<Object> list = redisEnv.opsForHash().values(preKey);
List<V> result = new ArrayList<>(list.size());
list.forEach(valueObject ->{
V value = parseValue(valueObject);
result.add(value);
});
return result;
}
@Override
public boolean isEmpty() {
return redisEnv.opsForHash().size(preKey) == 0;
}
//获取传入的泛型类
public void getGenType(){
this.keyType = new TypeToken<K>(getClass()) {}.getType();
this.valueType = new TypeToken<V>(getClass()) {}.getType();
}
public K parseKey(Object object){
if(object == null) return null;
return JSONObject.parseObject(object.toString(),keyType);
}
public V parseValue(Object object){
if(object == null) return null;
return JSONObject.parseObject(object.toString(),valueType);
}
private String serializeObject(Object object){
return JSONObject.toJSONString(object);
}
@Override
public int size() {
return redisEnv.opsForHash().size(preKey).intValue();
}
public String getPreKey() {
return preKey;
}
public void expire(long timeout, TimeUnit unit){
redisEnv.expire(this.preKey,timeout,unit);
}
}
附1:未知泛型类型实现方法
TypeToken<ChainNode<E>> chainNodeTypeToken = getChainNodeType(new TypeToken<E>(getClass()) {});
static <E extends AttachmentMsg> TypeToken<ChainNode<E>> getChainNodeType(TypeToken<E> valueType) {
return new TypeToken<ChainNode<E>>() {}
.where(new TypeParameter<E>() {}, valueType);
}
CatcherMap<String, ChainNode<E>> chainNodeMap = new RedisMap<String,ChainNode<E>>(redisEnv,this.chainNodeMapPreKey,chainNodeTypeToken.getType()){};