/** * 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; } }
版权声明:本文为snail_bi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。