redis实现数据的增删查改

一、springboot集成redis实现数据的增删查改

1、添加依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

因为我部署的是redis5.0.7版本,而springboot是从2.2.0版本开始集成redis5的stream类型,所以版本一定要高于2.2.0。不然是无法使用redis5版本的stream数据类型。当然如果不使用stream类型的话,版本可以适当低一点。

2、配置文件application.yaml

spring:
    application:
        name: redis-cluster-local
    redis:
        cluster:
            nodes: ip:port,ip:port... #cluster
        host: ip # standalone
        password: ''
        port: port
        timeout: 30000
        jedis:
            pool:
                max-active: 8
                max-idle: 8
                max-wait: -1ms
                min-idle: 0

3、启动类加注解(这一步可以省略:如果你的包结构合理的话)

@MapperScan(value = "com.nebula.springboot_redis.mapper")

项目结构如下:

redis 增删 hook点 redis增删改查_spring

4、写配置文件(同样可省略:使用springboot集成就是这么方便)

5、数据操作

stringRedisTemplate.opsForValue()...
stringRedisTemplate.opsForList()...
stringRedisTemplate.opsForSet()...
stringRedisTemplate.opsForZSet()...
stringRedisTemplate.opsForHash()...
stringRedisTemplate.opsForStream()...

二、redis原生API实现增删查改

1、添加依赖

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.1.0</version>
</dependency>

2、配置文件

这个就需要自己写了:

redis:
    jedis:
        block-when-exhausted: true
        cluster:
            host: ip:port,ip:port...
            password: ''
        pool:
            max-active: 1024
            max-idle: 200
            max-wait: 10000
            min-idle: 0
            timeout: 10000
        standalone:
            database: 0
            host: ip
            password: ''
            port: port

3、写配置类读取配置文件

@Configuration
@Slf4j
public class RedisConfig {

    @Value("${redis.jedis.standalone.host}")
    private String standaloneHost;

    @Value("${redis.jedis.cluster.host}")
    private String clusterHost;

    @Value("${redis.jedis.standalone.port}")
    private int standalonePort;

    @Value("${redis.jedis.standalone.password}")
    private String standalonePassword;

    @Value("${redis.jedis.pool.timeout}")
    private int timeout;

    @Value("${redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${redis.jedis.pool.max-active}")
    private int maxActive;

    @Value("${redis.jedis.pool.max-wait}")
    private long maxWaitMillis;

    @Value("${redis.jedis.block-when-exhausted}")
    private boolean blockWhenExhausted;

    @Bean
    public JedisPool redisPoolFactory() {
        log.info("redis地址:" + standaloneHost + ":" + standalonePort);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, standaloneHost, standalonePort, timeout);
        log.info("JedisPool注入成功!!");
        return jedisPool;
    }

    @Bean
    public JedisCluster redisClusterPoolFactory() {
        log.info("redis地址:" + clusterHost);
        String[] split = clusterHost.split(",");
        List<String> list = Arrays.asList(split);
        Set<HostAndPort> nodes = new HashSet<>();
        list.forEach(s -> {
            String[] ss = s.split(":");
            nodes.add(new HostAndPort(ss[0], Integer.parseInt(ss[1])));
        });
        JedisCluster jedisCluster = new JedisCluster(nodes);
        log.info("JedisCluster注入成功!!");
        return jedisCluster;
    }
}

4、数据操作

jedis = jedisPool.getResource();
jedis.select(indexDb);
return jedis.zcard(key);

三、特殊情况

看到上述区别,估计大家都会选择SpringBoot提供的模版来操作redis吧。但可惜的是:有时候springboot的版本并不是你想用什么版本就可以使用什么版本的。比如锁我们现在就是要求springboot版本为2.0.6,这时候使用springboot模板是不能操作stream,这时候就需要自己两种方式并行了。工具类如下:

package com.chinatower.framework.redis.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;

import java.util.*;

@Component("redisUtils")
@Slf4j
public class RedisUtils {
    private final StringRedisTemplate stringRedisTemplate;
    private final JedisPool jedisPool;
    private final JedisCluster jedisCluster;

    public RedisUtils(StringRedisTemplate stringRedisTemplate, JedisPool jedisPool, JedisCluster jedisCluster) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.jedisPool = jedisPool;
        this.jedisCluster = jedisCluster;
    }

    //==================string类型========================

    /**
     * 添加string类型值
     *
     * @param key     键
     * @param value   值
     * @param indexDb 数据库
     * @return 更改条数
     */
    public Integer set(String key, String value, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                stringRedisTemplate.opsForValue().set(key, value);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                jedis.set(key, value);
            }
            return 1;
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 获取string类型值
     *
     * @param key     键
     * @param indexDb 数据库
     * @return 值
     */
    public String get(String key, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForValue().get(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.get(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 查看值的长度
     *
     * @param key     键
     * @param indexDb 数据库
     * @return 长度
     */
    public Long length(String key, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForValue().size(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.strlen(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * string类型追加
     *
     * @param key     键
     * @param value   追加值
     * @param indexDb 数据库
     */
    public int append(String key, String value, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                stringRedisTemplate.opsForValue().append(key, value);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                jedis.append(key, value);
            }
            return 1;
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0;
        } finally {
            returnResource(jedis);
        }
    }


    //===============list操作=======================

    /**
     * 添加list类型
     *
     * @param key     键
     * @param list    值
     * @param indexDb 数据库
     * @return 改变的长度
     */
    public Long push(String key, List<String> list, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForList().rightPushAll(key, list);
            } else {
                String[] vals = list.toArray(new String[0]);
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.rpush(key, vals);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 读取list类型的值
     *
     * @param key     键
     * @param start   起始位置
     * @param end     终点位置
     * @param indexDb 数据库
     * @return 值
     */
    public List<String> lrange(String key, long start, long end, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForList().range(key, start, end);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.lrange(key, start, end);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ArrayList<>();
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 通过索引设置列表元素的值
     *
     * @param key     键
     * @param index   索引
     * @param value   值
     * @param indexDb 数据库
     */
    public void lset(String key, long index, String value, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                stringRedisTemplate.opsForList().set(key, index, value);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                jedis.lset(key, index, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 根据索引位置查询值
     *
     * @param key     键
     * @param index   索引
     * @param indexDb 数据库
     * @return 值
     */
    public String lindex(String key, long index, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForList().index(key, index);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.lindex(key, index);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 仅保留该区域的值
     *
     * @param key     键
     * @param start   起始位置
     * @param end     终点位置
     * @param indexDb 数据库
     */
    public void ltrim(String key, long start, long end, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                stringRedisTemplate.opsForList().trim(key, start, end);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                jedis.ltrim(key, start, end);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 查询list类型值的长度
     *
     * @param key     键
     * @param indexDb 数据库
     * @return 长度, 异常为0
     */
    public Long llen(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForList().size(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.llen(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 移除首尾元素并返回
     *
     * @param key     键
     * @param left    true为首, false为尾
     * @param indexDb 数据库
     * @return 移除的元素
     */
    public String lpop(String key, boolean left, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                if (left) {
                    return stringRedisTemplate.opsForList().leftPop(key);
                } else {
                    return stringRedisTemplate.opsForList().rightPop(key);
                }
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                if (left) {
                    return jedis.lpop(key);
                } else {
                    return jedis.rpop(key);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    //=============Set类型操作===============

    /**
     * 添加set类型数据
     *
     * @param key     键
     * @param values  值
     * @param indexDb 数据库
     * @return 添加成功的数量
     */
    public Long sadd(String key, Set<String> values, int indexDb) {
        Jedis jedis = null;
        try {
            String[] strings = values.toArray(new String[0]);
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().add(key, strings);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.sadd(key, strings);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 获取集合的成员数
     *
     * @param key     键
     * @param indexDb 数据库
     * @return 成员数
     */
    public Long scard(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().size(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.scard(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 从set数据里弹出多个数据
     *
     * @param key     键
     * @param count   数量
     * @param indexDb 数据库
     * @return collection<String></>
     */
    public List<String> spop(String key, long count, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().pop(key, count);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return new ArrayList<>(jedis.spop(key, count));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ArrayList<>();
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回集合中的随机元素。
     *
     * @param key     键
     * @param count   数量
     * @param indexDb 数据库
     * @return list集合,因为可能会重复
     */
    public List<String> srandmember(String key, int count, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().randomMembers(key, count);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.srandmember(key, count);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ArrayList<>();
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回set集合中全部元素
     *
     * @param key     键
     * @param indexDb 数据库
     * @return 集合中全部元素
     */
    public Set<String> smembers(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().members(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.smembers(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return new HashSet<>();
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 判断成员元素是否是集合的成员。
     *
     * @param key     键
     * @param value   值
     * @param indexDb 数据库
     * @return 存在为true
     */
    public Boolean sismember(String key, String value, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().isMember(key, value);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.sismember(key, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回给定集合之间的差集。不存在的集合 key 将视为空集。差集的结果来自前面的 FIRST_KEY
     *
     * @param key     第一个键
     * @param keys    后面的键
     * @param indexDb 数据库
     * @return 差集
     */
    public Set<String> sdiff(String key, List<String> keys, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().difference(key, keys);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                keys.add(0, key);
                String[] vals = keys.toArray(new String[0]);
                return jedis.sdiff(vals);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回给定集合之间的交集。不存在的集合 key 将视为空集。交集的结果来自前面的 FIRST_KEY
     *
     * @param key     第一个键
     * @param keys    后面的键
     * @param indexDb 数据库
     * @return 交集
     */
    public Set<String> sinter(String key, List<String> keys, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().intersect(key, keys);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                keys.add(0, key);
                String[] vals = keys.toArray(new String[0]);
                return jedis.sinter(vals);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回给定集合之间的并集。不存在的集合 key 将视为空集。
     *
     * @param key     第一个键
     * @param keys    后面的键
     * @param indexDb 数据库
     * @return 并集
     */
    public Set<String> sunion(String key, List<String> keys, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForSet().union(key, keys);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                keys.add(0, key);
                String[] vals = keys.toArray(new String[0]);
                return jedis.sunion(vals);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    //=============sorted set操作====================

    /**
     * 添加sorted set类型数据
     *
     * @param key     键
     * @param value   值
     * @param score   分数
     * @param indexDb 数据库
     * @return 更新条数
     */
    public Long zadd(String key, String value, double score, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                Boolean add = stringRedisTemplate.opsForZSet().add(key, value, score);
                if (add != null) {
                    return add ? 1L : 0L;
                } else {
                    return 0L;
                }
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zadd(key, score, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 查询集合长度
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public Long zcard(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().zCard(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zcard(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 计算在有序集合中指定区间分数的成员数
     *
     * @param key     键
     * @param min     最小值
     * @param max     最大值
     * @param indexDb 数据库
     * @return 成员数
     */
    public Long zcount(String key, double min, double max, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().count(key, min, max);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zcount(key, min, max);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    public Double zincrby(String key, double score, String value, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().incrementScore(key, value, score);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zincrby(key, score, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回有序集中,指定区间内的成员。
     *
     * @param key     键
     * @param start   以 0 表示有序集第一个成员,以 1 表示有序集第二个成员
     * @param end     以 -1 表示最后一个成员, -2 表示倒数第二个成员
     * @param indexDb 数据库
     * @return set<String></>
     */
    public Set<String> zrange(String key, long start, long end, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().range(key, start, end);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zrange(key, start, end);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 按索引返回有序集中,指定区间内的成员with分数(递减)
     *
     * @param key     键
     * @param start   起始坐标
     * @param end     终点坐标
     * @param indexDb 数据库
     * @return 键
     */
    public Map<String, Double> zrevrange(String key, long start, long end, int indexDb) {
        Jedis jedis = null;
        Map<String, Double> map = new HashMap<>();
        try {
            if (indexDb == -1) {
                Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
                Set<ZSetOperations.TypedTuple<String>> result = tuples != null ? tuples : new HashSet<>();
                result.forEach(tuple -> map.put(tuple.getValue(), tuple.getScore()));
                return map;
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                Set<Tuple> tuples = jedis.zrevrangeWithScores(key, start, end);
                tuples.forEach(tuple -> map.put(tuple.getElement(), tuple.getScore()));
                return map;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回有序集中,指定区间内的成员。
     *
     * @param key     键
     * @param min     最小分
     * @param max     最高分
     * @param indexDb 数据库
     * @return set<String></>
     */
    public Set<String> zrangeByScore(String key, double min, double max, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().rangeByScore(key, min, max);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zrangeByScore(key, min, max);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 按分数返回有序集中,指定区间内的成员with分数(递减)
     *
     * @param key     键
     * @param min     起始坐标
     * @param max     终点坐标
     * @param indexDb 数据库
     * @return 键
     */
    public Map<String, Double> zrevrangeByScore(String key, double min, double max, int indexDb) {
        Jedis jedis = null;
        Map<String, Double> map = new HashMap<>();
        try {
            if (indexDb == -1) {
                Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max);
                Set<ZSetOperations.TypedTuple<String>> result = tuples != null ? tuples : new HashSet<>();
                result.forEach(tuple -> map.put(tuple.getValue(), tuple.getScore()));
                return map;
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                Set<Tuple> tuples = jedis.zrevrangeByScoreWithScores(key, max, min);
                tuples.forEach(tuple -> map.put(tuple.getElement(), tuple.getScore()));
                return map;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public Long zrank(String key, String value, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().rank(key, value);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zrank(key, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    public Long zrem(String key, String value, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForZSet().remove(key, value);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.zrem(key, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    //================hash操作===================

    /**
     * 删除hash类型中字段
     *
     * @param key     键
     * @param field   字段
     * @param indexDb 数据库
     */
    public Long hdel(String key, String field, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForHash().delete(key, field);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.hdel(key, field);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 判断hash类型中字段是否存在
     *
     * @param key     键
     * @param field   字段
     * @param indexDb 数据库
     */
    public Boolean hexist(String key, String field, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForHash().hasKey(key, field);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.hexists(key, field);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 判断hash类型的大小
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public Long hsize(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.opsForHash().size(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.hlen(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 根据字段查询值
     *
     * @param key     键
     * @param field   字段
     * @param indexDb 数据库
     */
    public String hget(String key, String field, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return (String) stringRedisTemplate.opsForHash().get(key, field);

            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.hget(key, field);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 根据键查询所有字段
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public Set<String> hkeys(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                Set<Object> keys = stringRedisTemplate.opsForHash().keys(key);
                Set<String> set = new HashSet<>();
                keys.forEach(v -> set.add((String) v));
                return set;
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.hkeys(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 添加或修改字段
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public void hset(String key, Map<String, String> data, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                stringRedisTemplate.opsForHash().putAll(key, data);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                jedis.hset(key, data);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 查询hash类型的值
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public List<String> hvals(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                List<Object> values = stringRedisTemplate.opsForHash().values(key);
                List<String> list = new ArrayList<>();
                values.forEach(v -> list.add((String) v));
                return list;
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.hvals(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 遍历hash
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public Map<String, String> hscan(String key, String pattern, int count, int indexDb) {
        Jedis jedis = null;
        Map<String, String> map = new HashMap<>();
        String pat = "*" + pattern + "*";
        try {
            if (indexDb == -1) {
                Cursor<Map.Entry<Object, Object>> scan = stringRedisTemplate.opsForHash().scan(key, ScanOptions.scanOptions().match(pat).count(count).build());
                scan.forEachRemaining((obj) -> {
                    String key1 = (String) obj.getKey();
                    String value1 = (String) obj.getValue();
                    map.put(key1, value1);
                });
                return map;
            } else {
                String cursor = ScanParams.SCAN_POINTER_START;
                ScanParams scanParams = new ScanParams();
                scanParams.count(count);
                scanParams.match(pat);
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                List<Map.Entry<String, String>> result = jedis.hscan(key, cursor, scanParams).getResult();
                result.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
                return map;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    //=============stream操作========================

    /**
     * 添加或修改字段
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public StreamEntryID xadd(String key, Map<String, String> data, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.xadd(key, StreamEntryID.NEW_ENTRY, data);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.xadd(key, StreamEntryID.NEW_ENTRY, data);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 流中满足给定ID范围的条目,范围由最小和最大ID指定。
     *
     * @param key     键
     * @param start   起始
     * @param end     终止
     * @param count   终止
     * @param indexDb 数据库
     */
    public List<StreamEntry> xrange(String key, String start, String end, int count, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.xrange(key, new StreamEntryID(start), new StreamEntryID(end), count);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.xrange(key, new StreamEntryID(start), new StreamEntryID(end), count);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 从指定流中移除指定的条目,并返回成功删除的条目的数量
     * 在传递的ID不存在的情况下, 返回的数量可能与传递的ID数量不同。
     *
     * @param key     键
     * @param id      编号
     * @param indexDb 数据库
     */
    public Long xdel(String key, String id, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.xdel(key, new StreamEntryID(id));
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.xdel(key, new StreamEntryID(id));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返回流中的条目数
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public Long xlen(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.xlen(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.xlen(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 将流裁剪为指定数量的项目
     * 如有需要,将驱逐旧的项目(ID较小的项目)
     *
     * @param key     键
     * @param count   指定数量
     * @param indexDb 数据库
     */
    public Long xtrim(String key, int count, int indexDb, boolean exact) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.xtrim(key, count, exact);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.xtrim(key, count, exact);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }


    //=============关于键的操作=======================//

    /**
     * 查看键在redis中是否存在
     *
     * @param key     键
     * @param indexDb 数据库
     * @return true is exist
     */
    public boolean checkKeyExist(String key, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                Boolean hasKey = stringRedisTemplate.hasKey(key);
                return hasKey == null ? false : hasKey;
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.exists(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 检查key存储的类型
     *
     * @param key     键
     * @param indexDb 数据库
     * @return 类型
     */
    public String type(String key, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.type(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.type(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return "error";
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 设置键的存活时间
     *
     * @param key     键
     * @param time    时间:s
     * @param indexDb 数据库
     */
    public void expire(String key, Long time, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                jedisCluster.expire(key, time.intValue());
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                jedis.expire(key, time.intValue());
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 查询键的剩余存活时间
     *
     * @param key     键
     * @param indexDb 数据库
     */
    public Long ttl(String key, int indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.ttl(key);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.ttl(key);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 删除键
     *
     * @param key     键
     * @param indexDb 数据库
     * @return true is exist
     */
    public boolean del(String key, Integer indexDb) {
        Jedis jedis = null;
        try {
            if (indexDb == -1) {
                return jedisCluster.del(key) == 1;
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.del(key) == 1;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 查询符合规则的键
     * @param pattern 键
     * @param indexDb 数据库
     */
    public Set<String> pattern(String pattern, Integer indexDb) {
        Jedis jedis = null;
        pattern = "*" + pattern + "*";
        try {
            if (indexDb == -1) {
                return stringRedisTemplate.keys(pattern);
            } else {
                jedis = jedisPool.getResource();
                jedis.select(indexDb);
                return jedis.keys(pattern);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            returnResource(jedis);
        }
    }

    /**
     * 返还到连接池
     *
     * @param jedis 连接
     */
    private static void returnResource(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
}

完整项目已经上传至gitee,地址为:https://gitee.com/hschong/chinatower_redis.git。