基于jedis2.9.0的Redis缓存工具

Jedis是一个Java语言的Redis客户端,它提供了丰富的功能来与Redis数据库进行交互和操作。Jedis支持Redis支持的各种数据类型,如字符串、哈希、列表、集合、有序集合等,可以使用Jedis将数据存储到Redis中,并从Redis中获取数据。本工具是基于jedis2.9.0版本,如使用jedis的其它版本,替换后需自测。

1、在pom.xml中,引入依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

2、工具代码

2.1、配置类

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {

    @Bean("jedisPoolConfig")
    @ConfigurationProperties(prefix="spring.redis.pool-config")
    public JedisPoolConfig getRedisConfig(){
        JedisPoolConfig config = new JedisPoolConfig();
        return config;
    }

    @Bean
    public JedisPool jedisPool(
                               @Qualifier("jedisPoolConfig") JedisPoolConfig config,
                               @Value("${spring.redis.host}") String host,
                               @Value("${spring.redis.port}") int port,
                               @Value("${spring.redis.timeout}") int timeout,
                               @Value("${spring.redis.password}") String password,
                               @Value("${spring.redis.database}") int database) {
        return new JedisPool(config, host, port, timeout, password,database);
    }
}

2.2、全局异常类

@SuppressWarnings("serial")
public class RedisServiceException extends RuntimeException{

    public RedisServiceException(String msg) {
        super(msg);
    }

    public RedisServiceException(String msg, Exception e) {
        super(msg, e);
    }

    public RedisServiceException(Exception e) {
        super(e);
    }
}

2.3、工具方法类

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import javax.annotation.Resource;
import java.util.*;

/**
 * Redis调用客户端
 */
@Service
public class RedisClient {
    //private static Logger logger = LogManager.getLogger(RedisClient.class);

    @Resource
    private JedisPool jedisPool;

    public RedisClient() {

    }

    public RedisClient(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }


    /**
     * 设置一个key的过期时间(单位:秒)
     * @param key key值
     * @param seconds 多少秒后过期
     * @return 1:设置了过期时间  0:没有设置过期时间/不能设置过期时间
     *
     * [ɪkˈspaɪər]
     */
    public long expire(String key, int seconds) {
        if (key==null || key.equals("")) {
            return 0;
        }

        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.expire(key, seconds);
        } catch (Exception ex) {
            //logger.error("EXPIRE error[key=" + key + " seconds=" + seconds + "]" + ex.getMessage(), ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }

    /**
     * 设置一个key在某个时间点过期
     * @param key key值
     * @param unixTimestamp unix时间戳,从1970-01-01 00:00:00开始到现在的秒数
     * @return 1:设置了过期时间  0:没有设置过期时间/不能设置过期时间
     */
    public long expireAt(String key, int unixTimestamp) {
        if (key==null || key.equals("")) {
            return 0;
        }

        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.expireAt(key, unixTimestamp);
        } catch (Exception ex) {
            //logger.error("EXPIRE error[key=" + key + " unixTimestamp=" + unixTimestamp + "]" + ex.getMessage(), ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }

    /**
     * 截断一个List
     * @param key 列表key
     * @param start 开始位置 从0开始
     * @param end 结束位置
     * @return 状态码
     */
    public String trimList(String key, long start, long end) {
        if (key == null || key.equals("")) {
            return "-";
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.ltrim(key, start, end);
        } catch (Exception ex) {
            //logger.error("LTRIM 出错[key=" + key + " start=" + start + " end=" + end + "]" + ex.getMessage() , ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return "-";
    }
    /**
     * 检查Set长度
     * @param key
     * @return
     */
    public long scard(String key){
        if(key == null ){
            return 0;
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.scard(key);
        } catch (Exception ex) {
            //logger.error("countSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }
    /**
     * 添加到Set中(同时设置过期时间)
     * @param key key值
     * @param seconds 过期时间 单位s
     * @param value
     * @return
     */
    public boolean sadd(String key,int seconds, String... value) {
        boolean result = sadd(key, value);
        if(result){
            long i = expire(key, seconds);
            return i==1;
        }
        return false;
    }
    /**
     * 添加到Set中
     * @param key
     * @param value
     * @return
     */
    public boolean sadd(String key, String... value) {
        if(key == null || value == null){
            return false;
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.sadd(key, value);
            return true;
        } catch (Exception ex) {
            //logger.error("setList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }


    /**
     * 判断值是否包含在set中
     * @param key
     * @param value
     * @return true:在  false:不在
     */
    public boolean sismember(String key, String value) {
        if(key == null || value == null){
            return false;
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.sismember(key, value);
        } catch (Exception ex) {
            //logger.error("setList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 获取集合中所有的元素
     * @param key
     * @return
     */
    public  Set<String> smembers(String key){
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.smembers(key);
        } catch (Exception ex) {
            //logger.error("getList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 从set中删除value
     * @param key
     * @return
     */
    public  boolean srem(String key,String... value){
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.srem(key, value);
            return true;
        } catch (Exception ex) {
            //logger.error("getList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 从集合中随机取一个元素
     * @param key
     * @return
     */
    public String srandmember(String key) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.srandmember(key);
        } catch (Exception ex) {
            //logger.error("getList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return "";
    }

    /**
     * 从list中删除value 默认count 1
     * @param key
     * @param values 值list
     * @return
     */
    public  int removeListValue(String key,List<String> values){
        return removeListValue(key, 1, values);
    }

    /**
     * 从list中删除value
     * @param key
     * @param count
     * @param values 值list
     * @return
     */
    public  int removeListValue(String key,long count,List<String> values){
        int result = 0;
        if(values != null && values.size()>0){
            for(String value : values){
                if(removeListValue(key, count, value)){
                    result++;
                }
            }
        }
        return result;
    }
    /**
     *  从list中删除value
     * @param key
     * @param count 要删除个数
     * @param value
     * @return
     */
    public  boolean removeListValue(String key,long count,String value){
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.lrem(key, count, value);
            return true;
        } catch (Exception ex) {
            //logger.error("getList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 截取List
     * @param key
     * @param start 起始位置
     * @param end 结束位置
     * @return
     */
    public List<String> rangeList(String key, long start, long end) {
        if (key == null || key.equals("")) {
            return null;
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.lrange(key, start, end);
        } catch (Exception ex) {
            //logger.error("rangeList 出错[key=" + key + " start=" + start + " end=" + end + "]" + ex.getMessage() , ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 检查List长度
     * @param key
     * @return
     */
    public long llen(String key){
        if(key == null ){
            return 0;
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.llen(key);
        } catch (Exception ex) {
            //logger.error("countList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }

    /**
     * 添加到List中(同时设置过期时间)
     * @param key key值
     * @param seconds 过期时间 单位s
     * @param value
     * @return
     */
    public boolean lpush(String key,int seconds, String... value){
        boolean result = lpush(key, value);
        if(result){
            long i = expire(key, seconds);
            return i==1;
        }
        return false;
    }
    /**
     * 添加到List
     * @param key
     * @param value
     * @return
     */
    public boolean lpush(String key, String... value) {
        if(key == null || value == null){
            return false;
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.lpush(key, value);
            return true;
        } catch (Exception ex) {
            //logger.error("setList error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    public String lindex(String key, int index) {
        if(key == null){
            return "";
        }
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.lindex(key, index);
        } catch (Exception ex) {
            //logger.error("lindex error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return "";
    }

    /**
     * 添加到List(只新增)
     * @param key
     * @return
     */
    public boolean lpush(String key, List<String> list) {
        if(key == null || list == null || list.size() == 0){
            return false;
        }
        for(String value : list){
            lpush(key, value);
        }
        return true;
    }

    /**
     * 获取List
     * @param key
     * @return
     */
    public  List<String> lrange(String key){
        return lrange(key, 0, -1);
    }

    /**
     * 获取List中数据
     * @param key
     * @param start
     * @param end
     * @return
     */
    public List<String> lrange(String key, int start, int end) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.lrange(key, start, end);
        } catch (Exception ex) {
            //logger.error("lrange error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 获取队列数据
     * @param key 键名
     * @return
     */
    public  byte[] rpop(byte[] key) {

        byte[] bytes = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            bytes = jedis.rpop(key);

        } catch (Exception ex) {
            //logger.error("setList error.", ex);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return bytes;
    }

    /**
     * 获取队列数据
     * @return
     */
    public List<String> brpop(int seconds,String key) {

        List<String> result = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.brpop(seconds,key);

        } catch (Exception ex) {
            //logger.error("setList error.", ex);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return result;
    }
    /**
     *
     * @param key
     * @return
     */
    public String rpop(String key){
        String data = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            data=jedis.rpop(key);
        } catch (Exception ex) {
            //logger.error("setList error.", ex);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return data;
    }

    public long ttl(String key) {
        if (key==null || key.equals("")) {
            return 0;
        }

        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.ttl(key);
        } catch (Exception ex) {
            //logger.error("EXPIRE error[key=" + key + "]" + ex.getMessage(), ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }
    /**
     * 设置HashSet对象
     *
     * @param domain 域名
     * @param key    键值
     * @param value  Json String or String value
     * @return
     */
    public boolean setHSet(String domain, String key, String value) {
        if (value == null) return false;
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.hset(domain, key, value);
            return true;
        } catch (Exception ex) {
            //logger.error("setHSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 获得HashSet对象
     *
     * @param domain 域名
     * @param key    键值
     * @return Json String or String value
     */
    public String getHSet(String domain, String key) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.hget(domain, key);
        } catch (Exception ex) {
            //logger.error("getHSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 删除HashSet对象
     *
     * @param domain 域名
     * @param key    键值
     * @return 删除的记录数
     */
    public long delHSet(String domain, String key) {
        Jedis Jedis = null;
        long count = 0;
        try {
            Jedis = jedisPool.getResource();
            count = Jedis.hdel(domain, key);
        } catch (Exception ex) {
            //logger.error("delHSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return count;
    }

    /**
     * 删除HashSet对象
     *
     * @param domain 域名
     * @param key    键值
     * @return 删除的记录数
     */
    public long delHSet(String domain, String... key) {
        Jedis Jedis = null;
        long count = 0;
        try {
            Jedis = jedisPool.getResource();
            count = Jedis.hdel(domain, key);
        } catch (Exception ex) {
            //logger.error("delHSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return count;
    }

    /**
     * 判断key是否存在
     *
     * @param key key值
     * @param field hash健值
     * @return value
     */
    public boolean existsHSet(String key, String field) {
        Jedis Jedis = null;
        boolean isExist = false;
        try {
            Jedis = jedisPool.getResource();
            isExist = Jedis.hexists(key, field);
        } catch (Exception ex) {
            //logger.error("existsHSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return isExist;
    }

    /**
     * 全局扫描hset
     *
     * @param match field匹配模式
     * @return
     */
    public List<Map.Entry<String, String>> scanHSet(String domain, String match) {
        Jedis jedis = null;
        try {
            int cursor = 0;
            jedis = jedisPool.getResource();
            ScanParams scanParams = new ScanParams();
            scanParams.match(match);
//            Jedis jedis = Jedis.ge getShard(domain);
            ScanResult<Map.Entry<String, String>> scanResult;
            List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>();
            do {
                scanResult = jedis.hscan(domain, String.valueOf(cursor), scanParams);
                list.addAll(scanResult.getResult());
                cursor = Integer.parseInt(scanResult.getStringCursor());
            } while (cursor > 0);
            return list;
        } catch (Exception ex) {
            //logger.error("scanHSet error.", ex);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return null;
    }


    /**
     * 返回 domain 指定的哈希集中所有字段的value值
     *
     * @param domain
     * @return
     */

    public List<String> hvals(String domain) {
        Jedis Jedis = null;
        List<String> retList = null;
        try {
            Jedis = jedisPool.getResource();
            retList = Jedis.hvals(domain);
        } catch (Exception ex) {
            //logger.error("hvals error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return retList;
    }

    /**
     * 返回 domain 指定的哈希集中所有字段的key值
     *
     * @param domain
     * @return
     */

    public Set<String> hkeys(String domain) {
        Jedis Jedis = null;
        Set<String> retList = null;
        try {
            Jedis = jedisPool.getResource();
            retList = Jedis.hkeys(domain);
        } catch (Exception ex) {
            //logger.error("hkeys error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return retList;
    }

    /**
     * 返回 domain 指定的哈希key值总数
     *
     * @param domain
     * @return
     */
    public long lenHset(String domain) {
        Jedis Jedis = null;
        long retList = 0;
        try {
            Jedis = jedisPool.getResource();
            retList = Jedis.hlen(domain);
        } catch (Exception ex) {
            //logger.error("hkeys error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return retList;
    }

    /**
     * 设置排序集合
     *
     * @param key
     * @param score
     * @param value
     * @return
     */
    public boolean setSortedSet(String key, long score, String value) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.zadd(key, score, value);
            return true;
        } catch (Exception ex) {
            //logger.error("setSortedSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 获得排序集合
     *
     * @param key
     * @param startScore
     * @param endScore
     * @param orderByDesc
     * @return
     */
    public Set<String> getSoredSet(String key, long startScore, long endScore, boolean orderByDesc) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            if (orderByDesc) {
                return Jedis.zrevrangeByScore(key, endScore, startScore);
            } else {
                return Jedis.zrangeByScore(key, startScore, endScore);
            }
        } catch (Exception ex) {
            //logger.error("getSoredSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 计算排序长度
     *
     * @param key
     * @param startScore
     * @param endScore
     * @return
     */
    public long countSoredSet(String key, long startScore, long endScore) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Long count = Jedis.zcount(key, startScore, endScore);
            return count == null ? 0L : count;
        } catch (Exception ex) {
            //logger.error("countSoredSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0L;
    }

    /**
     * 删除排序集合
     *
     * @param key
     * @param value
     * @return
     */
    public boolean delSortedSet(String key, String value) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            long count = Jedis.zrem(key, value);
            return count > 0;
        } catch (Exception ex) {
            //logger.error("delSortedSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 获得排序集合
     *
     * @param key
     * @param startRange
     * @param endRange
     * @param orderByDesc
     * @return
     */
    public Set<String> getSoredSetByRange(String key, int startRange, int endRange, boolean orderByDesc) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            if (orderByDesc) {
                return Jedis.zrevrange(key, startRange, endRange);
            } else {
                return Jedis.zrange(key, startRange, endRange);
            }
        } catch (Exception ex) {
            //logger.error("getSoredSetByRange error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 获得排序打分
     *
     * @param key
     * @return
     */
    public Double getScore(String key, String member) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.zscore(key, member);
        } catch (Exception ex) {
            //logger.error("getSoredSet error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return null;
    }

    /**
     * 添加一个key-value, 同时设置有效期
     * @param key
     * @param value
     * @param second 有效期(秒)
     * @return
     */
    public boolean set(String key, String value, int second) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.setex(key, second, value);
            return true;
        } catch (Exception ex) {
            //logger.error("set error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 添加一个key-value
     * @param key
     * @param value
     * @return
     */
    public boolean set(String key, String value) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.set(key, value);
            return true;
        } catch (Exception ex) {
            //logger.error("set error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 根据key,查找值
     * @param key
     * @param defaultValue 如果没有找到,返回此值
     * @return
     */
    public String get(String key, String defaultValue) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return StringUtils.defaultIfEmpty(Jedis.get(key), defaultValue);
        } catch (Exception ex) {
            //logger.error("get error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return defaultValue;
    }

    /**
     * 删除一个键
     * @param key
     * @return
     */
    public boolean del(String key) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.del(key);
            return true;
        } catch (Exception ex) {
            //logger.error("del error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 原子加1
     * @param key key
     * @return 加过后的数字
     */
    public long incr(String key) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.incr(key);
        } catch (Exception ex) {
            //logger.error("incr error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }

    /**
     * 原子减1
     * @param key key
     * @return 减后的值
     */
    public long decr(String key) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.decr(key);
        } catch (Exception ex) {
            //logger.error("decr error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return 0;
    }

    /**
     * 将一个Java对象序列化为JSON字符串
     * @param object 要序列化的对象
     * @return JSON字符串
     */
    public static String serialize(Object object) {
        if (object == null) return null;
        try {
            return JSON.toJSONString(object);
        } catch (Exception ex) {
            //logger.error("serialize error.", ex);
        }
        return null;
    }

    /**
     * 将一个JSON字符串反序列化为对象
     * @param value JSON字符串
     * @param clazz 对象class
     * @param <T> 返回对象
     * @return
     */
    public static <T> T unserialize(String value, Class<T> clazz) {
        if (value == null) return null;
        try {
            return JSON.parseObject(value, clazz);
        } catch (Exception e) {
            //logger.error("unserialize error.", e);
        }
        return null;
    }

    /**
     * 获取锁
     * @param key
     * @return
     */
    public boolean lock(String key) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Long result = Jedis.setnx(key, "1");
            return result == 1;
        } catch (Exception ex) {
            //logger.error("lock-setnx error:", ex);
            returnBrokenResource(Jedis);
            throw new RedisServiceException("获取锁出现异常:" + ex.getMessage(), ex);
        } finally {
            returnResource(Jedis);
        }
    }

    public boolean set(String key, String value, String nxxx, int second) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            Jedis.set(key, value, nxxx, "seconds",second);
            return true;
        } catch (Exception ex) {
            //logger.error("set error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return false;
    }

    /**
     * 获取锁
     * Redis 分布式锁是 Redis 提供的一种用来实现分布式锁的特性,它使用 setnx 命令和 expire 命令实现。
     * 原理是通过在 Redis 中设置一个 key,并设置 key 的过期时间,
     * 当多个客户端同时尝试获取锁时,只有一个客户端能成功设置 key 的过期时间,并获取到锁,
     * 其他客户端则会在设置 key 的过期时间时失败,并在设置 key 的过期时间失败后进行重试,直到获取到锁。
     * @param key
     * @param expireSecond
     * @return
     */
    public boolean lock(String key, int expireSecond) {

        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            String result = Jedis.set(key, "1", "NX","EX",expireSecond);
            if(StringUtils.isEmpty(result))
                return false;

            if("OK".compareTo(result)==0){
                return true;
            }
            return false;
        } catch (Exception ex) {
            //logger.error("lock-setnx error:", ex);
            returnBrokenResource(Jedis);
            throw new RedisServiceException("获取锁出现异常:" + ex.getMessage(), ex);
        } finally {
            returnResource(Jedis);
        }
    }

    /**
     * 获取锁,如果没有获取到会再去尝试几次
     *
     * @param key 锁键值
     * @param expireSecond 锁过期时间
     * @param tryCount 尝试次数
     * @return 是否获得锁
     */
    @SuppressWarnings("static-access")
    public boolean tryLock(String key, int expireSecond, int tryCount) {
        if (lock(key, expireSecond)) {
            return true;
        }

        for (int i=0; i<tryCount; i++) {
            int sleepMills = RandomUtils.nextInt(20, 200);
            try {
                Thread.currentThread().sleep(sleepMills);
            } catch (InterruptedException e) {
                //logger.error(e, e);
            }

            if (lock(key, expireSecond)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 释放锁
     * @param key
     */
    public void unlock(String key) {
        del(key);
    }

    @SuppressWarnings("deprecation")
    private void returnBrokenResource(Jedis Jedis) {
        try {
            jedisPool.returnBrokenResource(Jedis);
        } catch (Exception e) {
            //logger.error("returnBrokenResource error.", e);
        }
    }

    @SuppressWarnings("deprecation")
    private void returnResource(Jedis Jedis) {
        try {
            jedisPool.returnResource(Jedis);
        } catch (Exception e) {
            //logger.error("returnResource error.", e);
        }
    }

    /**
     * 向缓存中设置对象
     *
     * @param key   存储的key
     * @param value 存储的value
     * @return 是否成功
     */
    public boolean setObject(String key, Object value) {
        return set(key,JSON.toJSONString(value));
    }
    public boolean setObject(String key, Object value, int second) {
        return set(key,JSON.toJSONString(value), second);
    }

    /**
     * 根据key 获取对象
     *
     * @param key 存储的key
     * @return 获取的对象
     */

    public <T> T getObject(String key, Class<T> clazz) {
        try {
            String value = get(key, "");
            if(org.springframework.util.StringUtils.isEmpty(value)){
                return null;
            }
            return JSON.parseObject(value, clazz);
        } catch (Exception e) {
            //logger.error("get redis but json error : " + e + "\r\nkey:" + key);
        }
        return null;
    }

    /**
     * 模糊查询特定规则key
     * @param parrten
     * @param defaultValue 如果没有找到,返回此值
     * @return
     */
    public Set<String> getKeys(String parrten, Set<String> defaultValue) {
        Jedis Jedis = null;
        try {
            Jedis = jedisPool.getResource();
            return Jedis.keys(parrten);
        } catch (Exception ex) {
            //logger.error("get error.", ex);
            returnBrokenResource(Jedis);
        } finally {
            returnResource(Jedis);
        }
        return Collections.EMPTY_SET;
    }
}

3、简单使用

3.1、配置application.yml

      在springboot项目的application.yml文件中增加Redis配置,配置参考示例如下:

spring:
  redis:
    database: 0
    host: 127.0.0.1
    password: #密码
    port: 6379
    timeout: 3000
    commandTimeout: 3000
    pool-config:
      maxTotal: 256
      maxIdle: 10
      numTestsPerEvictionRun: 1024
      timeBetweenEvictionRunsMillis: 30000
      minEvictableIdleTimeMillis: -1
      softMinEvictableIdleTimeMillis: 10000
      maxWaitMillis: 1500
      testOnBorrow: true
      testWhileIdle: true
      testOnReturn: false
      jmxEnabled: true
      jmxNamePrefix: 
      blockWhenExhausted: false
      minIdle: 0
      maxActive: 8
      maxWait: -1

3.2、服务接口

import java.util.Set;

public interface RedisService {

    //写数据
    public String writeMessage(String key,String message);

    //读数据
    public String readMessage(String key);

    //锁测试
    public String lockTest(String key);

    //模拟-点赞
    public String like(long userId,long worksId);

    //模拟-取消点赞
    public String noLike(long userId, long worksId);

    //模拟-查看是否点赞
    public String hasLike(long userId,long worksId);

    //模拟- 点赞统计
    public String likeCount(long worksId);

    //模拟-点赞用户列表
    public Set<String> likeUserList(long worksId);


    //队列 左进右出
    //...
}

3.3、实现服务接口

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Set;

@Service
public class RedisServiceImpl implements RedisService {

    @Resource
    //单例
    private RedisClient redisClient;

    @Override
    public String writeMessage(String key,String message){
        boolean setResult = redisClient.set(key,message,300);
        return "send success.";
    }

    @Override
    public String readMessage(String key){
        String ss = redisClient.get(key,"default");
        return ss;
    }

    @Override
    public String lockTest(String key) {
        String lockKey = "lock:"+key;
        boolean getlock = false;
        try{
            getlock = redisClient.tryLock(lockKey,30,2);
        } catch (Exception ex){
            ex.printStackTrace();
        }
        String msg = "";
        try {
            if(!getlock){
                msg = "获取锁失败";
                return msg;
            }
            msg = "获取锁成功";

        } catch (Exception ex){
           ex.printStackTrace();
        } finally {
            //释放锁
            redisClient.unlock(lockKey);
        }
        return msg;
    }

    @Override
    public String like(long userId, long worksId) {
        boolean r = redisClient.sadd("works_like_users::" + worksId,String.valueOf(userId));
        return String.valueOf(r);
    }

    @Override
    public String noLike(long userId, long worksId) {
        boolean r = redisClient.srem("works_like_users::" + worksId,String.valueOf(userId));
        return String.valueOf(r);
    }

    @Override
    public String hasLike(long userId, long worksId) {
        boolean r = redisClient.sismember("works_like_users::" + worksId,String.valueOf(userId));
        return String.valueOf(r);
    }

    @Override
    public String likeCount(long worksId) {
        long r = redisClient.scard("works_like_users::" + worksId);
        return String.valueOf(r);
    }

    @Override
    public Set<String> likeUserList(long worksId) {
        Set<String> r = redisClient.smembers("works_like_users::" + worksId);
        return r;
    }

}

3.4、测试接口

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.Set;

@Controller
public class RedisController {

    @Resource
    private RedisService redisService;

    @RequestMapping(value="/writeMessage")
    @ResponseBody
    public String writeMessage() {
        return redisService.writeMessage("redis-test","redisValue");
    }


    @RequestMapping(value="/lockTest")
    @ResponseBody
    public String lockTest(String key){
        return redisService.lockTest(key);
    }

    //点赞
    @RequestMapping(value="/like")
    @ResponseBody
    public String like(long userId,long worksId){
        return redisService.like(userId,worksId);
    }

    //取消点赞
    @RequestMapping(value="/noLike")
    @ResponseBody
    public String nolike(long userId,long worksId){
        
        return redisService.noLike(userId,worksId);
    }

    //查看是否点赞
    @RequestMapping(value="/hasLike")
    @ResponseBody
    public String hasLike(long userId,long worksId){
        return redisService.hasLike(userId,worksId);
    }

    //点赞统计
    @RequestMapping(value="/likeCount")
    @ResponseBody
    public String likeCount(long worksId){
        return redisService.likeCount(worksId);
    }

    //点赞用户列表
    @RequestMapping(value="/likeUserList")
    @ResponseBody
    public Set<String> likeUserList(long worksId){
        return redisService.likeUserList(worksId);
    }

}

        以上内容仅供参考!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用Jedis 2.9.0实现分布式锁的示例: ```java import redis.clients.jedis.Jedis; import redis.clients.jedis.params.SetParams; public class JedisDistributedLock { private static final String LOCK_KEY = "mylock"; private static final int EXPIRE_TIME = 10000; private static final int WAIT_TIME = 5000; private Jedis jedis; public JedisDistributedLock() { this.jedis = new Jedis("localhost"); } public boolean acquireLock() { long start = System.currentTimeMillis(); while (System.currentTimeMillis() - start < WAIT_TIME) { SetParams params = new SetParams().nx().ex(EXPIRE_TIME); String result = jedis.set(LOCK_KEY, "locked", params); if (result != null && result.equals("OK")) { return true; } try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } return false; } public void releaseLock() { jedis.del(LOCK_KEY); } } ``` 在上述示例中,我们首先定义了一个常量锁键“mylock”,以及一个超时时间和等待时间,然后实现了一个acquireLock()方法和一个releaseLock()方法。 在acquireLock()方法中,我们循环尝试获取锁,直到等待时间超时或者成功获取锁。我们使用Jedis的set()方法来设置锁键,使用nx()参数来保证只有在锁键不存在的情况下才会设置成功,使用ex()参数来设置超时时间。如果set()方法返回OK,则说明成功获取了锁,返回true。否则,我们睡眠一段时间再重试。 在releaseLock()方法中,我们直接删除锁键即可。 请注意,上述示例中的分布式锁并不是完美的,因为它不能保证锁的可重入性和公平性。如果您需要更加完善的分布式锁实现,请考虑使用RedLock等算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值