封装JedisClient.提供API实现对redis的操作

JedisClient Redis 操作示例
本文介绍了一个 Java 实现的 JedisClient 类,用于简化 Redis 的操作。包括键值对的设置与获取、批量操作、数值型键的递增与递减等功能。

需要导包,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();
        try {
            
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑点燃希望

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值