/**
* The type Jedis client.
*
* @author wangsiyu
* @date 2019.10.22
*/
@Slf4j
@Component
public class JedisClient {
/**
* The constant SIMPLE_CLASS_OBJ.
*/
private static final List<Class<?>> SIMPLE_CLASS_OBJ = Lists.newArrayList();
/**
* LOCK_SUCCESS
*/
private static final String LOCK_SUCCESS = "OK";
/**
* SET_IF_NOT_EXIST
*/
private static final String SET_IF_NOT_EXIST = "NX";
/**
* SET_WITH_EXPIRE_TIME
*/
private static final String SET_WITH_EXPIRE_TIME = "PX";
/**
* RELEASE_SUCCESS
*/
private static final Long RELEASE_SUCCESS = 1L;
static {
SIMPLE_CLASS_OBJ.add(Number.class);
SIMPLE_CLASS_OBJ.add(String.class);
SIMPLE_CLASS_OBJ.add(Boolean.class);
}
/**
* The Jedis pool.
*/
@Resource
private JedisPool jedisPool;
/**
* The Redis db index.
*/
@Setter
private Integer redisDbIndex;
/**
* Is simple obj boolean.
*
* @param classObj the class obj
* @return the boolean
*/
private static boolean isSimpleObj(Class<?> classObj) {
for (Class<?> c : SIMPLE_CLASS_OBJ) {
if (c.isAssignableFrom(classObj)) {
return true;
}
}
return false;
}
/**
* 嘗試獲取鎖並設定有效時間 @param lock the lock
*
* @param lock lock
* @param expired the expired
* @return the boolean
*/
public Boolean acquireLock(final String lock, final int expired){
final Object result = runTask(new Callback() {
@Override
public Boolean onTask(Jedis jedis) {
jedis.select(redisDbIndex);
long value = System.currentTimeMillis() + expired + 1;
long acquired = jedis.setnx(lock, String.valueOf(value));
if (acquired == 1) {
jedis.expire(lock, expired);
return true;
}
return false;
}
});
return (Boolean)result;
}
/**
* 釋放鎖資源 @param lock the lock
*
* @param lock lock
*/
public void releaseLock(final String lock){
runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(redisDbIndex);
long currentTime = System.currentTimeMillis();
if (currentTime < Long.valueOf(jedis.get(lock))){
jedis.del(lock);
}
return null;
}
});
}
/**
* Set boolean.
*
* @param key the key
* @param seconds the seconds
* @param value the value
* @return the boolean
*/
public boolean set(final String key, final int seconds, final Object value) {
return set(redisDbIndex, key, seconds, value);
}
/**
* Set boolean.
*
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param value the value
* @return the boolean
*/
public boolean set(final int dbIndex, final String key, final int seconds, final Object value) {
if (key == null || value == null) {
return false;
}
Object succeed = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
String ret;
if (isSimpleObj(value.getClass())) {
if (seconds == CacheTime.CACHE_EXP_FOREVER) {
ret = jedis.set(key, value.toString());
} else {
ret = jedis.setex(key, seconds, value.toString());
}
} else {
byte[] bKey = SafeEncoder.encode(key);
byte[] bValue = serialize(value);
if (seconds == CacheTime.CACHE_EXP_FOREVER) {
ret = jedis.set(bKey, bValue);
} else {
ret = jedis.setex(bKey, seconds, bValue);
}
}
return "OK".equals(ret);
}
});
return succeed != null && (boolean) succeed;
}
/**
* 設定一個hash物件
*
* @param key 雜湊表中的key
* @param seconds the seconds
* @param field 域
* @param value 值
* @return 如果是第一次建立 ,則返回true,否則為false
*/
public boolean setHash(final String key, final int seconds, final String field, final Object value) {
return setHash(redisDbIndex, key, seconds, field, value);
}
/**
* Sets hash.
*
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param field the field
* @param value the value
* @return the hash
*/
public boolean setHash(final int dbIndex, final String key, final int seconds, final String field, final Object
value) {
if (key == null || field == null || value == null) {
return false;
}
Object succeed = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
if (isSimpleObj(value.getClass())) {
ret = jedis.hset(key, field, value.toString());
} else {
byte[] bKey = SafeEncoder.encode(key);
byte[] bField = SafeEncoder.encode(field);
byte[] bValue = serialize(value);
ret = jedis.hset(bKey, bField, bValue);
}
if (seconds != CacheTime.CACHE_EXP_FOREVER) {
jedis.expire(key, seconds);
}
return ret != null && ret == 1;
}
});
return succeed != null && (boolean) succeed;
}
/**
* Gets hash.
*
* @param <T> the type parameter
* @param key the key
* @param field the field
* @param cls the cls
* @return the hash
*/
public <T> T getHash(final String key, final String field, final Class<T> cls) {
return getHash(redisDbIndex, key, field, cls);
}
/**
* Gets hash.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param field the field
* @param cls the cls
* @return the hash
*/
@SuppressWarnings("unchecked")
public <T> T getHash(final int dbIndex, final String key, final String field, final Class<T> cls) {
if (field == null) {
throw new IllegalArgumentException("field can not null");
}
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Object obj = null;
if (isSimpleObj(cls)) {
String str = jedis.hget(key, field);
if (str != null) {
obj = createSimpleObj(str, cls);
}
} else {
byte[] bs = jedis.hget(SafeEncoder.encode(key), SafeEncoder.encode(field));
if (bs != null) {
obj = deserialize(bs);
}
}
return obj;
}
});
return ret == null ? null : (T) ret;
}
/**
* Gets hash.
*
* @param <T> the type parameter
* @param key the key
* @param cls the cls
* @param fields the fields
* @return the hash
*/
public <T> List<T> getHash(final String key, final Class<T> cls, final String... fields) {
return getHash(redisDbIndex, key, cls, fields);
}
/**
* Gets hash map.
*
* @param <T> the type parameter
* @param key the key
* @param cls the cls
* @param fields the fields
* @return the hash map
*/
public <T> Map<String, T> getHashMap(String key, Class<T> cls, String... fields) {
List<T> list = getHash(key, cls, fields);
if (list == null) {
return null;
}
Map<String, T> map = Maps.newHashMap();
for (int i = 0; i < fields.length; i++) {
map.put(fields[i], list.get(i));
}
return map;
}
/**
* Gets hash.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param cls the cls
* @param fields the fields
* @return the hash
*/
@SuppressWarnings("unchecked")
public <T> List<T> getHash(final int dbIndex, final String key, final Class<T> cls, final String... fields) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
final byte[][] bfields = new byte[fields.length][];
for (int i = 0; i < bfields.length; i++) {
bfields[i] = SafeEncoder.encode(fields[i]);
}
List<byte[]> bytes = jedis.hmget(SafeEncoder.encode(key), bfields);
if (bytes == null) {return null;}
List<T> retList = Lists.newArrayList();
boolean isSimple = isSimpleObj(cls);
for (byte[] e : bytes) {
if (e == null) {
retList.add(null);
continue;
}
retList.add(isSimple ? createSimpleObj(SafeEncoder.encode(e), cls) : (T) deserialize(e));
}
return retList;
}
});
return ret == null ? null : (List<T>) ret;
}
/**
* sorted set 新增
*
* @param <T> the type parameter
* @param key the key
* @param seconds the seconds
* @param score the score
* @param member the member
* @return the long
*/
public <T> Long zadd(final String key,final int seconds,final double score, final String member) {
return zadd(redisDbIndex, key, seconds,score, member);
}
/**
* Zadd long.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param score the score
* @param member the member
* @return the long
*/
public <T> Long zadd(final int dbIndex,final String key,final int seconds,final double score, final String member) {
if (key == null || member == null) {
return 0L;
}
Object rs = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
byte[] bMember = SafeEncoder.encode(member);
ret = jedis.zadd(bKey,score,bMember);
if (seconds != CacheTime.CACHE_EXP_FOREVER) {
jedis.expire(key, seconds);
}
return ret == null ? 0 : ret;
}
});
return (Long) rs;
}
/**
* 獲取有序集合成員數
*
* @param key the key
* @return the long
*/
public Long zcard(final String key) {
return zcard(redisDbIndex,key);
}
/**
* Zcard long.
*
* @param dbIndex the db index
* @param key the key
* @return the long
*/
public Long zcard(final int dbIndex, final String key) {
if (key == null) {
return 0L;
}
Object length = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
ret = jedis.zcard(bKey);
return ret == null ? 0 : ret;
}
});
return (Long) length;
}
/**
* 移除有序集合中的一個成員
*
* @param <T> the type parameter
* @param key the key
* @param val the val
* @return the long
*/
public <T> Long zrem(final String key, final String val) {
return zrem(redisDbIndex, key, val);
}
/**
* Zrem long.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param val the val
* @return the long
*/
public <T> Long zrem(final int dbIndex, final String key, final String val) {
if (key == null || val == null) {
return 0L;
}
Object rs = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
byte[] bMember = SafeEncoder.encode(val);
ret = jedis.zrem(bKey,bMember);
return ret == null ? 0 : ret;
}
});
return (Long) rs;
}
/**
* 返回有序集合中指定分數區間的成員列表由小到大
*
* @param <T> the type parameter
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> zRang(final String key, final Long start, final Long end) {
return zRang(redisDbIndex, key, start, end);
}
/**
* Z rang list.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> zRang(final int dbIndex, final String key, final Long start, final Long end) {
if (key == null || start == null || end == null) {
return Lists.newArrayList();
}
Object obj = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Set<byte[]> rbyteSet;
byte[] bKey = SafeEncoder.encode(key);
rbyteSet = jedis.zrange(bKey, start, end);
List<T> retList = Lists.newArrayList();
for (byte[] rbyte : rbyteSet) {
retList.add((T)SafeEncoder.encode(rbyte));
}
return retList;
}
});
return (List<T>) obj;
}
/**
* 返回有序集合中指定分數區間的成員列表有大到小
*
* @param <T> the type parameter
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> zRevRANGE (final String key, final Long start, final Long end) {
return zRevRange(redisDbIndex, key, start, end);
}
/**
* Z rev range list.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> zRevRange(final int dbIndex, final String key, final Long start, final Long end) {
if (key == null || start == null || end == null) {
return Lists.newArrayList();
}
Object obj = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Set<byte[]> rbyteSet;
byte[] bKey = SafeEncoder.encode(key);
rbyteSet = jedis.zrevrange(bKey, start, end);
List<T> retList = Lists.newArrayList();
for (byte[] rbyte : rbyteSet) {
retList.add((T)SafeEncoder.encode(rbyte));
}
return retList;
}
});
return (List<T>) obj;
}
/**
* Z rang by score list.
*
* @param <T> the type parameter
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> zRangByScore(final String key, final Double start, final Double end) {
return zRangByScore(redisDbIndex, key, start, end);
}
/**
* Z rang by score list.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> zRangByScore(final int dbIndex, final String key, final Double start, final Double end) {
if (key == null || start == null || end == null) {
return Lists.newArrayList();
}
Object obj = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Set<byte[]> rbyteSet;
byte[] bKey = SafeEncoder.encode(key);
rbyteSet = jedis.zrangeByScore(bKey, start, end);
List<T> retList = Lists.newArrayList();
for (byte[] rbyte : rbyteSet) {
retList.add((T)SafeEncoder.encode(rbyte));
}
return retList;
}
});
return (List<T>) obj;
}
/**
* 獲取list的size
*
* @param key the key
* @return the list size
*/
public long getListSize(final String key) {
return getListSize(redisDbIndex, key);
}
/**
* 獲取list的size
*
* @param dbIndex the db index
* @param key the key
* @return the list size
*/
public long getListSize(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.llen(key);
}
});
return ret == null ? 0 : (long) ret;
}
/**
* 獲取list所有元素
*
* @param <T> the type parameter
* @param key the key
* @return the list range
*/
public <T> List<T> getListRange(final String key) {
return getListRange(redisDbIndex, key);
}
/**
* 獲取list所有元素
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @return the list range
*/
@SuppressWarnings("unchecked")
public <T> List<T> getListRange(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.lrange(key, 0, jedis.llen(key) - 1);
}
});
return ret == null ? Collections.<T>emptyList() : (List<T>) ret;
}
/**
* 獲取list所有元素
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @return the list
*/
@SuppressWarnings("unchecked")
public <T> List<T> lrange(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.lrange(key, 0, -1);
}
});
return ret == null ? Collections.<T>emptyList() : (List<T>) ret;
}
/**
* 獲取key下面所有的值,string的
*
* @param <K> the type parameter
* @param <V> the type parameter
* @param key the key
* @return the key all
*/
public <K, V> Map<K, V> getKeyAll(final String key) {
return getKeyAll(redisDbIndex, key);
}
/**
* 獲取key下面所有的值,string的
*
* @param <K> the type parameter
* @param <V> the type parameter
* @param dbIndex the db index
* @param key the key
* @return the key all
*/
@SuppressWarnings("unchecked")
public <K, V> Map<K, V> getKeyAll(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.hgetAll(key);
}
});
return ret == null ? Collections.<K, V>emptyMap() : (Map<K, V>) ret;
}
/**
* 獲取指定指定index的list儲存物件
*
* @param <T> the type parameter
* @param key the key
* @param index the index
* @param cls the cls
* @return the list
*/
public <T> T getList(final String key, final int index, final Class<T> cls) {
return getList(redisDbIndex, key, index, cls);
}
/**
* Gets list.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param index the index
* @param cls the cls
* @return the list
*/
@SuppressWarnings("unchecked")
public <T> T getList(final int dbIndex, final String key, final int index, final Class<T> cls) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Object obj = null;
if (isSimpleObj(cls)) {
String str = jedis.lindex(key, index);
if (str != null) {
obj = createSimpleObj(str, cls);
}
} else {
byte[] bs = jedis.lindex(SafeEncoder.encode(key), index);
if (bs != null) {
obj = deserialize(bs);
}
}
return obj;
}
});
return ret == null ? null : (T) ret;
}
/**
* 講一批物件推送到list中
*
* @param key the key
* @param seconds the seconds
* @param values the values
* @return the boolean
*/
public boolean pushList(final String key, final int seconds, final Object... values) {
return pushList(redisDbIndex, key, seconds, values);
}
/**
* Push list boolean.
*
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param values the values
* @return the boolean
*/
public boolean pushList(final int dbIndex, final String key, final int seconds, final Object... values) {
if (key == null || values == null || values.length == 0) {
return false;
}
Object succeed = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
if (isSimpleObj(values.getClass())) {
String[] array = new String[values.length];
for (int i = 0; i < values.length; i++) {
array[i] = values[i].toString();
}
ret = jedis.lpush(key, array);
} else {
byte[] bKey = SafeEncoder.encode(key);
byte[][] array = new byte[values.length][];
for (int i = 0; i < values.length; i++) {
array[i] = serialize(values[i]);
}
ret = jedis.lpush(bKey, array);
}
if (seconds != CacheTime.CACHE_EXP_FOREVER) {
jedis.expire(key, seconds);
}
return ret != null && ret == 1;
}
});
return succeed != null && (boolean) succeed;
}
/**
* Lpush list boolean.
*
* @param <T> the type parameter
* @param key the key
* @param value the value
* @return the boolean
*/
@SuppressWarnings("unchecked")
public <T> boolean lpushList(final String key, final T value) {
return lpushList(redisDbIndex, key, CacheTime.CACHE_EXP_WEEK, value);
}
/**
* Lpush list boolean.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param value the value
* @return the boolean
*/
@SuppressWarnings("unchecked")
public <T> boolean lpushList(final int dbIndex, final String key, final T value) {
return lpushList(dbIndex, key, CacheTime.CACHE_EXP_WEEK, value);
}
/**
* Lpush list boolean.
*
* @param <T> the type parameter
* @param key the key
* @param seconds the seconds
* @param values the values
* @return the boolean
*/
@SuppressWarnings("unchecked")
public <T> boolean lpushList(final String key, final Integer seconds, final T... values) {
return lpushList(redisDbIndex, key, seconds, values);
}
/**
* Lpush list boolean.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param values the values
* @return the boolean
*/
@SuppressWarnings("unchecked")
public <T> boolean lpushList(final int dbIndex, final String key, final Integer seconds, final T... values) {
if (key == null || values == null || values.length == 0) {
return false;
}
Object succeed = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
byte[][] array = new byte[values.length][];
for (int i = 0; i < values.length; i++) {
array[i] = serialize(values[i]);
}
ret = jedis.lpush(bKey, array);
if (seconds != CacheTime.CACHE_EXP_FOREVER) {
jedis.expire(key, seconds);
}
return ret != null && ret > 0;
}
});
return succeed != null && (boolean) succeed;
}
/**
* Range list list.
*
* @param <T> the type parameter
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public <T> List<T> rangeList(final String key, final Long start, final Long end) {
return rangeList(redisDbIndex, key, start, end);
}
/**
* Range list list.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
@SuppressWarnings("unchecked")
public <T> List<T> rangeList(final int dbIndex, final String key, final Long start, final Long end) {
if (key == null || start == null || end == null) {
return Lists.newArrayList();
}
Object obj = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
List<byte[]> rbyteList;
byte[] bKey = SafeEncoder.encode(key);
rbyteList = jedis.lrange(bKey, start, end);
List<T> retList = Lists.newArrayList();
for (byte[] rbyte : rbyteList) {
retList.add((T) deserialize(rbyte));
}
return retList;
}
});
return (List<T>) obj;
}
/**
* Trim list boolean.
*
* @param key the key
* @param start the start
* @param end the end
* @return the boolean
*/
public Boolean trimList(final String key, final Long start, final Long end) {
return trimList(redisDbIndex, key, start, end);
}
/**
* Trim list boolean.
*
* @param dbIndex the db index
* @param key the key
* @param start the start
* @param end the end
* @return the boolean
*/
public Boolean trimList(final int dbIndex, final String key, final Long start, final Long end) {
if (key == null || start == null || end == null) {
return Boolean.FALSE;
}
Object succeed = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
String ret;
byte[] bKey = SafeEncoder.encode(key);
ret = jedis.ltrim(bKey, start, end);
return "OK".equals(ret);
}
});
return succeed != null && (boolean) succeed;
}
/**
* 對hash表中的某個元素執行增加操作,如果操作的field非數字,則結果返回null.如果是負數,就是減少
*
* @param key the key
* @param field the field
* @param value 需要增加的值
* @return 增加之後的值 ,如果操作的field非數字,則結果返回null
*/
public Long incrHash(final String key, final String field, final long value) {
return incrHash(redisDbIndex, key, field, value);
}
/**
* Incr hash long.
*
* @param dbIndex the db index
* @param key the key
* @param field the field
* @param value the value
* @return the long
*/
public Long incrHash(final int dbIndex, final String key, final String field, final long value) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.hincrBy(key, field, value);
}
});
return ret == null ? null : (Long) ret;
}
/**
* Incr hash double.
*
* @param key the key
* @param field the field
* @param value the value
* @return the double
*/
public Double incrHash(final String key, final String field, final double value) {
return incrHash(redisDbIndex, key, field, value);
}
/**
* Incr hash double.
*
* @param dbIndex the db index
* @param key the key
* @param field the field
* @param value the value
* @return the double
*/
public Double incrHash(final int dbIndex, final String key, final String field, final double value) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.hincrByFloat(key, field, value);
}
});
return ret == null ? null : (Double) ret;
}
/**
* Get t.
*
* @param <T> the type parameter
* @param key the key
* @param cls the cls
* @return the t
*/
public <T> T get(final String key, final Class<T> cls) {
return get(redisDbIndex, key, cls);
}
/**
* Get t.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param cls the cls
* @return the t
*/
@SuppressWarnings("unchecked")
public <T> T get(final int dbIndex, final String key, final Class<T> cls) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Object obj = null;
if (isSimpleObj(cls)) {
String str = jedis.get(key);
if (str != null) {
obj = createSimpleObj(str, cls);
}
} else {
byte[] bs = jedis.get(SafeEncoder.encode(key));
if (bs != null) {
obj = deserialize(bs);
}
}
return obj;
}
});
return ret == null ? null : (T) ret;
}
/**
* Sadd ns long.
*
* @param <T> the type parameter
* @param key the key
* @param value the value
* @param seconds the seconds
* @return the long
*/
public <T> Long saddNS(String key,String value, final int seconds) {
return sadd(redisDbIndex, key, seconds, value);
}
/**
* Sadd ns long.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param value the value
* @return the long
*/
//這裡不判斷簡單型別和物件,和其他的有所不同,請注意
public <T> Long saddNS(final int dbIndex, final String key, final int seconds, final String value) {
if (key == null || value == null) {
return 0L;
}
Object rs = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
byte[] bValue =SafeEncoder.encode(value);
ret = jedis.sadd(bKey, bValue);
if (seconds != CacheTime.CACHE_EXP_FOREVER) {
jedis.expire(key, seconds);
}
return ret == null ? 0 : ret;
}
});
return (Long) rs;
}
/**
* Smember set.
*
* @param <T> the type parameter
* @param key the key
* @return the set
*/
public <T> Set<T> smember(String key) {
return smember(redisDbIndex, key);
}
/**
* Smember set.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @return the set
*/
//這裡不判斷簡單型別和物件,和其他的有所不同,請注意
public <T> Set<T> smember(final int dbIndex, final String key) {
if (key == null ) {
return null;
}
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
byte[] bKey = SafeEncoder.encode(key);
Set<byte[]> smembers = jedis.smembers(bKey);
Set<String> set = new HashSet<>();
if(CollectionUtil.isNotEmpty(smembers)){
for(byte[] b:smembers){
set.add(new String(b));
}
}
return set ;
}
});
return (Set<T>) ret;
}
/**
* Sadd long.
*
* @param <T> the type parameter
* @param key the key
* @param value the value
* @param seconds the seconds
* @return the long
*/
public <T> Long sadd(String key, T value, final int seconds) {
return sadd(redisDbIndex, key, seconds, value);
}
/**
* Sadd long.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param seconds the seconds
* @param value the value
* @return the long
*/
//這裡不判斷簡單型別和物件,和其他的有所不同,請注意
public <T> Long sadd(final int dbIndex, final String key, final int seconds, final T value) {
if (key == null || value == null) {
return 0L;
}
Object rs = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
byte[] bValue = serialize(value);
ret = jedis.sadd(bKey, bValue);
if (seconds != CacheTime.CACHE_EXP_FOREVER) {
jedis.expire(key, seconds);
}
return ret == null ? 0 : ret;
}
});
return (Long) rs;
}
/**
* Slen long.
*
* @param key the key
* @return the long
*/
public Long slen(final String key) {
return slen(redisDbIndex, key);
}
/**
* Slen long.
*
* @param dbIndex the db index
* @param key the key
* @return the long
*/
public Long slen(final int dbIndex, final String key) {
if (key == null) {
return 0L;
}
Object length = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
ret = jedis.scard(bKey);
return ret == null ? 0 : ret;
}
});
return (Long) length;
}
/**
* Srem long.
*
* @param <T> the type parameter
* @param key the key
* @param val the val
* @return the long
*/
public <T> Long srem(final String key, final T val) {
return srem(redisDbIndex, key, val);
}
/**
* Srem long.
*
* @param <T> the type parameter
* @param dbIndex the db index
* @param key the key
* @param val the val
* @return the long
*/
public <T> Long srem(final int dbIndex, final String key, final T val) {
if (key == null || val == null) {
return 0L;
}
Object rs = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
Long ret;
byte[] bKey = SafeEncoder.encode(key);
byte[] bVal = serialize(val);
ret = jedis.srem(bKey, bVal);
return ret == null ? 0 : ret;
}
});
return (Long) rs;
}
/**
* Create simple obj t.
*
* @param <T> the type parameter
* @param arg the arg
* @param cls the cls
* @return the t
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private <T> T createSimpleObj(String arg, Class<T> cls) {
T ret = null;
Constructor[] constructors = cls.getDeclaredConstructors();
for (Constructor t : constructors) {
Class[] parameterTypes = t.getParameterTypes();
if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) {
try {
ret = (T) t.newInstance(arg);
} catch (Exception e) {
log.error("create simple obj error: " + e.getMessage(), e);
}
break;
}
}
return ret;
}
/**
* Delete long.
*
* @param key the key
* @return the long
*/
public Long delete(final String key) {
return delete(redisDbIndex, key);
}
/**
* Delete long.
*
* @param dbIndex the db index
* @param key the key
* @return the long
*/
public Long delete(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.del(key);
}
});
return ret == null ? 0L : (long) ret;
}
public void deleteBatch(final int dbIndex, final List<String> keys) {
Object ret = runTask(jedis -> {
jedis.select(dbIndex);
Pipeline pipelined = jedis.pipelined();
for (String key : keys) {
pipelined.del(key);
}
pipelined.sync();
return null;
});
}
/**
* Del hash field long.
*
* @param key the key
* @param field the field
* @return the long
*/
public Long delHashField(final String key, final String field) {
return delHashField(redisDbIndex, key, field);
}
/**
* Del hash field long.
*
* @param dbIndex the db index
* @param key the key
* @param field the field
* @return the long
*/
public Long delHashField(final int dbIndex, final String key, final String field) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.hdel(key, field);
}
});
return ret == null ? 0L : (long) ret;
}
/**
* Incr by long.
*
* @param dbIndex the db index
* @param key the key
* @param value the value
* @return the long
*/
public long incrBy(final int dbIndex, final String key, final long value) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.incrBy(key, value);
}
});
return ret == null ? 0L : (long) ret;
}
/**
* Decr by long.
*
* @param key the key
* @param value the value
* @return the long
*/
public long decrBy(final String key, final long value) {
return decrBy(redisDbIndex, key, value);
}
/**
* Decr by long.
*
* @param dbIndex the db index
* @param key the key
* @param value the value
* @return the long
*/
public long decrBy(final int dbIndex, final String key, final long value) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.incrBy(key, -value);
}
});
return ret == null ? 0L : (long) ret;
}
/**
* Incr long.
*
* @param key the key
* @return the long
*/
//i++
public long incr(final String key) {
return incr(redisDbIndex, key);
}
/**
* Incr long.
*
* @param dbIndex the db index
* @param key the key
* @return the long
*/
public long incr(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.incr(key);
}
});
return ret == null ? 0L : (long) ret;
}
/**
* Run task object.
*
* @param callback the callback
* @return the object
*/
private Object runTask(Callback callback) {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
return callback.onTask(jedis);
} catch (JedisException e) {
broken = handleJedisException(e);
} catch (Exception e) {
log.error("Redis runTask error: ", e);
} finally {
closeResource(jedis, broken);
jedis = null;
}
return null;
}
/**
* Serialize byte [ ].
*
* @param object the object
* @return the byte [ ]
*/
private byte[] serialize(Object object) {
if (!(object instanceof Serializable)) {
throw new IllegalArgumentException("設定快取的物件:" + object.getClass() + "無法序列化,確保 implements Serializable");
}
ObjectOutputStream objOS = null;
ByteArrayOutputStream byteAOS = new ByteArrayOutputStream();
try {
objOS = new ObjectOutputStream(byteAOS);
objOS.writeObject(object);
return byteAOS.toByteArray();
} catch (Exception e) {
log.error("serialize error: " + e.getMessage());
} finally {
try {
if (objOS != null) {objOS.close();}
byteAOS.close();
} catch (IOException e) {
log.error("serialize close error : " + e.getMessage());
}
}
return null;
}
/**
* Deserialize object.
*
* @param bytes the bytes
* @return the object
*/
private Object deserialize(byte[] bytes) {
ByteArrayInputStream byteAIS = new ByteArrayInputStream(bytes);
ObjectInputStream objIS = null;
try {
objIS = new ObjectInputStream(byteAIS);
return objIS.readObject();
} catch (Exception e) {
log.error("deserialize error: " + e.getMessage());
} finally {
try {
byteAIS.close();
if (objIS != null) {objIS.close();}
} catch (IOException e) {
log.error("deserialize close error: " + e.getMessage());
}
}
return null;
}
/**
* The TTL command returns the remaining time to live in seconds of a key
* that has an {expire(String, int) EXPIRE} set. This introspection
* capability allows a Redis client to check how many seconds a given key
* will continue to be part of the dataset.
*
* @param key key
* @return Integer reply, returns the remaining time to live in seconds of a key that has an EXPIRE. In Redis 2.6 or older, if the Key does not exists or does not have an associated expire, -1 is returned. In Redis 2.8 or newer, if the Key does not have an associated expire, -1 is returned or if the Key does not exists, -2 is returned.
*/
public Long ttl(final String key) {
return ttl(redisDbIndex, key);
}
/**
* Ttl long.
*
* @param dbIndex the db index
* @param key the key
* @return the long
*/
public Long ttl(final int dbIndex, final String key) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.ttl(key);
}
});
return ret == null ? 0L : (long) ret;
}
/**
* Flush db string.
*
* @param dbIndex the db index
* @return the string
*/
public String flushDB(final int dbIndex) {
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.flushDB();
}
});
if (ret instanceof String){
return ret == null ? "0" : (String) ret;
}
return "0";
}
/**
* The interface Callback.
*
* @author wangsiyu
* @date 2019.10.22
*/
interface Callback {
/**
* On task object.
*
* @param jedis the jedis
* @return the object
*/
Object onTask(Jedis jedis);
}
/**
* Handle jedisException, write log and return whether the connection is broken.
*
* @param jedisException the jedis exception
* @return the boolean
*/
private boolean handleJedisException(JedisException jedisException) {
if (jedisException instanceof JedisConnectionException) {
log.error("Redis connection lost.", jedisException);
} else if (jedisException instanceof JedisDataException) {
if ((jedisException.getMessage() != null) && (jedisException.getMessage().indexOf("READONLY") != -1)) {
log.error("Redis connection are read-only slave.", jedisException);
} else {
// dataException, isBroken=false
return false;
}
} else {
log.error("Jedis exception happen.", jedisException);
}
return true;
}
/**
* Return jedis connection to the pool, call different return methods depends on the conectionBroken status.
*
* @param jedis the jedis
* @param conectionBroken the conection broken
*/
private void closeResource(Jedis jedis, boolean conectionBroken) {
try {
if (conectionBroken) {
jedisPool.returnBrokenResource(jedis);
} else {
jedisPool.returnResource(jedis);
}
} catch (Exception e) {
log.error("return back jedis failed, will fore close the jedis.", e);
jedis.close();
}
}
/**
* Keys set.
*
* @param patternStr the pattern str
* @return the set
*/
public Set<String> keys(String patternStr){
return keys(redisDbIndex, patternStr);
}
/**
* Keys set.
*
* @param dbIndex the db index
* @param patternStr the pattern str
* @return the set
*/
public Set<String> keys(final int dbIndex, final String patternStr){
Object ret = runTask(new Callback() {
@Override
public Object onTask(Jedis jedis) {
jedis.select(dbIndex);
return jedis.keys(patternStr);
}
});
if (ret == null){
return Sets.newHashSet();
}
Set<String> result = (Set<String>) ret;
return result;
}
}