須要導包,jedis-2.8.1.jar和博主的序列化工具類SerializeUtils
package com.demo.redis; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import redis.clients.jedis.BinaryJedisCluster; import redis.clients.jedis.BinaryJedisPubSub; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPubSub; import redis.clients.util.Pool; import redis.clients.util.SafeEncoder; import com.demo.utils.SerializeUtils; /** * JedisClient api 添加了中文註釋,便於工程師更方便使用,另外還原樣保持了 Jedis api 的方法名稱及使用方法,以便於僅僅經過查看 * Redis 文檔 便可快速掌握使用方法 Redis 命令參考: http://redisdoc.com/ */ public class JedisClient { private final String name; private final JedisPool jedisPool; private final BinaryJedisCluster cluster; private final boolean isCluster; public BinaryJedisCluster getCluster() { return cluster; } public Pool<Jedis> getJedisPool() { return jedisPool; } private final ThreadLocal<Jedis> threadLocalJedis = new ThreadLocal<Jedis>(); public JedisClient(String name, JedisPool jedisPool, BinaryJedisCluster cluster) { this.name = name; this.jedisPool = jedisPool; this.cluster = cluster; this.isCluster = this.cluster != null; } /** * 存放 key value 對到 redis 若是 key 已經持有其餘值, SET 就覆寫舊值,無視類型。 * 對於某個本來帶有生存時間(TTL)的鍵來講, 當 SET 命令成功在這個鍵上執行時, 這個鍵原有的 TTL 將被清除。 */ public String set(String key, Object value) { return isCluster ? clusterSet(key, value) : jedisSet(key, value); } private String clusterSet(String key, Object value) { if (value == null) { cluster.del(keyToBytes(key)); return null; } else { return cluster.set(keyToBytes(key), valueToBytes(value)); } } private String jedisSet(String key, Object value) { Jedis jedis = getJedis(); try { if (value == null) { jedis.del(keyToBytes(key)); return null; } else { return jedis.set(keyToBytes(key), valueToBytes(value)); } } finally { close(jedis); } } /** * 存放 key value 對到 redis 若是 key 已經持有其餘值, SET 就覆寫舊值,無視類型。 * 對於某個本來帶有生存時間(TTL)的鍵來講, 當 SET 命令成功在這個鍵上執行時, 這個鍵原有的 TTL 將被清除。 */ public void update(String key, Object value) { if (isCluster) { clusterUpdate(key, value); } else { jedisUpdate(key, value); } } private void clusterUpdate(String key, Object value) { Jedis jedis = getJedis(); try { byte[] bytes = keyToBytes(key); if (value == null) { cluster.del(bytes); } else { Long ttl = cluster.ttl(bytes); if (ttl > 0) { cluster.setex(bytes, ttl.intValue(), valueToBytes(value)); } else { cluster.set(bytes, valueToBytes(value)); } } } finally { close(jedis); } } private void jedisUpdate(String key, Object value) { Jedis jedis = getJedis(); try { byte[] bytes = keyToBytes(key); if (value == null) { jedis.del(bytes); } else { Long ttl = jedis.pttl(bytes); if (ttl > 0) { jedis.psetex(bytes, ttl, valueToBytes(value)); } else { jedis.set(bytes, valueToBytes(value)); } } } finally { close(jedis); } } /** * 存放 key value 對到 redis,並將 key 的生存時間設爲 seconds (以秒爲單位)。 若是 key 已經存在, SETEX * 命令將覆寫舊值。 */ public String setex(String key, int seconds, Object value) { return isCluster ? clusterSetex(key, seconds, value) : jedisSetex(key, seconds, value); } public String clusterSetex(String key, int seconds, Object value) { if (value == null) { cluster.del(keyToBytes(key)); return null; } return cluster.setex(keyToBytes(key), seconds, valueToBytes(value)); } public String jedisSetex(String key, int seconds, Object value) { Jedis jedis = getJedis(); try { if (value == null) { jedis.del(keyToBytes(key)); return null; } return jedis.setex(keyToBytes(key), seconds, valueToBytes(value)); } finally { close(jedis); } } /** * 返回 key 所關聯的 value 值 若是 key 不存在那麼返回特殊值 nil 。 */ @SuppressWarnings("unchecked") public <T> T get(String key) { Jedis jedis = getJedis(); try { return (T) valueFromBytes(jedis.get(keyToBytes(key))); } finally { close(jedis); } } /** * 返回 key 所關聯的 value 值 若是 key 不存在那麼返回特殊值 nil 。 */ @SuppressWarnings("unchecked") public <T> List<T> getList(List<String> keys) { if (keys == null) { return Collections.emptyList(); } Jedis jedis = getJedis(); try { List<T> list = new ArrayList<T>(); for (String key : keys) { list.add((T) valueFromBytes(jedis.get(keyToBytes(key)))); } return list; } finally { close(jedis); } } /** * 刪除給定的一個 key 不存在的 key 會被忽略。 */ public long del(String key) { Jedis jedis = getJedis(); try { return jedis.del(keyToBytes(key)); } finally { close(jedis); } } /** * 刪除給定的多個 key 不存在的 key 會被忽略。 * * @param <T> */ public <T> long del(List<T> keys) { if (keys == null) { return 0; } Jedis jedis = getJedis(); try { return jedis.del(keysToBytesList(keys)); } finally { close(jedis); } } /** * 刪除給定的多個 key 開頭的 * * @param <T> */ public void clear(String region) { Jedis jedis = getJedis(); try { Set<String> keys = jedis.keys(region + ":*"); if (keys == null || keys.size() == 0) { return; } jedis.del(keysToBytesSet(keys)); } finally { close(jedis); } } /** * 刪除給定的多個 key 不存在的 key 會被忽略。 */ public long del(String... keys) { if (keys == null) { return 0; } Jedis jedis = getJedis(); try { return jedis.del(keysToBytesArray(keys)); } finally { close(jedis); } } /** * 查找全部符合給定模式 pattern 的 key 。 KEYS * 匹配數據庫中全部 key 。 KEYS h?llo 匹配 hello , * hallo 和 hxllo 等。 KEYS h*llo 匹配 hllo 和 heeeeello 等。 KEYS h[ae]llo 匹配 hello * 和 hallo ,但不匹配 hillo 。 特殊符號用 \ 隔開 */ public Set<String> keys(String pattern) { Jedis jedis = getJedis(); try { return jedis.keys(pattern); } finally { close(jedis); } } /** * 同時設置一個或多個 key-value 對。 若是某個給定 key 已經存在,那麼 MSET * 會用新值覆蓋原來的舊值,若是這不是你所但願的效果,請考慮使用 MSETNX 命令:它只會在全部給定 key 都不存在的狀況下進行設置操做。 * MSET 是一個原子性(atomic)操做,全部給定 key 都會在同一時間內被設置,某些給定 key 被更新而另外一些給定 key * 沒有改變的狀況,不可能發生。 * * <pre> * 例子: * Cache cache = RedisKit.use(); // 使用 Redis 的 cache * cache.mset("k1", "v1", "k2", "v2"); // 放入多個 key value 鍵值對 * List list = cache.mget("k1", "k2"); // 利用多個鍵值獲得上面代碼放入的值 * </pre> */ public String mset(String... keysValues) { if (keysValues.length % 2 != 0) throw new IllegalArgumentException("wrong number of arguments for met, keysValues length can not be odd"); Jedis jedis = getJedis(); try { byte[][] kv = new byte[keysValues.length][]; for (int i = 0; i < keysValues.length; i++) { if (i % 2 == 0) kv[i] = keyToBytes(keysValues[i]); else kv[i] = valueToBytes(keysValues[i]); } return jedis.mset(kv); } finally { close(jedis); } } /** * 返回全部(一個或多個)給定 key 的值。 若是給定的 key 裏面,有某個 key 不存在,那麼這個 key 返回特殊值 nil * 。所以,該命令永不失敗。 */ @SuppressWarnings("rawtypes") public List mget(String... keys) { Jedis jedis = getJedis(); try { byte[][] keysBytesArray = keysToBytesArray(keys); List<byte[]> data = jedis.mget(keysBytesArray); return valueListFromBytesList(data); } finally { close(jedis); } } /** * 將 key 中儲存的數字值減一。 若是 key 不存在,那麼 key 的值會先被初始化爲 0 ,而後再執行 DECR 操做。 * 若是值包含錯誤的類型,或字符串類型的值不能表示爲數字,那麼返回一個錯誤。 本操做的值限制在 64 位(bit)有符號數字表示以內。 * 關於遞增(increment) / 遞減(decrement)操做的更多信息,請參見 INCR 命令。 */ public Long decr(String key) { Jedis jedis = getJedis(); try { return jedis.decr(keyToBytes(key)); } finally { close(jedis); } } /** * 將 key 所儲存的值減去減量 decrement 。 若是 key 不存在,那麼 key 的值會先被初始化爲 0 ,而後再執行 DECRBY * 操做。 若是值包含錯誤的類型,或字符串類型的值不能表示爲數字,那麼返回一個錯誤。 本操做的值限制在 64 位(bit)有符號數字表示以內。 * 關於更多遞增(increment) / 遞減(decrement)操做的更多信息,請參見 INCR 命令。 */ public Long decrBy(String key, long longValue) { Jedis jedis = getJedis(); try { return jedis.decrBy(keyToBytes(key), longValue); } finally { close(jedis); } } /** * 將 key 中儲存的數字值增一。 若是 key 不存在,那麼 key 的值會先被初始化爲 0 ,而後再執行 INCR 操做。 * 若是值包含錯誤的類型,或字符串類型的值不能表示爲數字,那麼返回一個錯誤。 本操做的值限制在 64 位(bit)有符號數字表示以內。 */ public Long incr(String key) { Jedis jedis = getJedis(); try { return jedis.incr(keyToBytes(key)); } finally { close(jedis); } } /** * 將 key 所儲存的值加上增量 increment 。 若是 key 不存在,那麼 key 的值會先被初始化爲 0 ,而後再執行 INCRBY * 命令。 若是值包含錯誤的類型,或字符串類型的值不能表示爲數字,那麼返回一個錯誤。 本操做的值限制在 64 位(bit)有符號數字表示以內。 * 關於遞增(increment) / 遞減(decrement)操做的更多信息,參見 INCR 命令。 */ public Long incrBy(String key, long longValue) { Jedis jedis = getJedis();