Springboot集成Redis

系列文章目录


一、引入依赖

maven的pom文件展示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lin</groupId>
    <artifactId>redis</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>
        <!-- redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

    </dependencies>
</project>

二、配置redis客户端信息

在application.yml中加入redis信息:
application.yml展示

server:
  port: 8082

spring:
  redis:
    host: 127.0.0.1
    port: 6378
    password: 123456
    database: 0
    timeout: 60000ms
    lettuce:
      pool:
        max-active: 10
        max-idle: 10
        min-idle: 5
        max-wait: 60000ms

三、配置redis.conf

package com.lin.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.lin.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;

/**
 * @author:junlin.ru
 * @description: redis配置
 * @Date:2021/7/27 11:11
*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
	
	@Autowired
    private LettuceConnectionFactory lettuceConnectionFactory;
	
	private Duration timeToLive = Duration.ofSeconds(60);

    /**
     *  在没有指定缓存Key的情况下,key生成策略
     * @return KeyGenerator
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     *  缓存管理器 使用Lettuce,和jedis有很大不同
     * @return CacheManager 缓存管理器
     */
    @Bean
    @Primary
    @Override
    public CacheManager cacheManager() {

        //关键点,spring cache的注解使用的序列化都从这来,没有这个配置的话使用的jdk自己的序列化,实际上不影响使用,只是打印出来不适合人眼识别
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()

                //key序列化方式
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))

                //value序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))

                .disableCachingNullValues()

                //缓存过期时间
                .entryTtl(timeToLive);


        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder
                .fromConnectionFactory(lettuceConnectionFactory)
                .cacheDefaults(config)
                .transactionAware();

        return builder.build();
    }


    /**
     *  RedisTemplate配置 在单独使用redisTemplate的时候 重新定义序列化方式
     * @return RedisTemplate<String, Object>
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();

        // value值的序列化采用fastJsonRedisSerializer
        template.setValueSerializer(valueSerializer());
        template.setHashValueSerializer(valueSerializer());
        template.setHashKeySerializer(keySerializer());

        // key的序列化采用StringRedisSerializer
        template.setKeySerializer(keySerializer());
        template.setConnectionFactory(lettuceConnectionFactory);
        template.afterPropertiesSet();

        return template;
    }

    private RedisSerializer<String> keySerializer() {
        return new StringRedisSerializer();
    }

    private RedisSerializer<Object> valueSerializer() {

        // 设置序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);

        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
        //序列化时允许非常量字段均输出类型
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        return jackson2JsonRedisSerializer;
    }


    @Bean(name = "redisUtils")
    public RedisUtils redisUtil(RedisTemplate<String, Object> redisTemplate) {
        RedisUtils redisUtils = new RedisUtils();
        redisUtils.setRedisTemplate(redisTemplate);
        return redisUtils;
    }

}

四、redis工具类

package com.lin.utils;

import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Description: redis工具类
 * @Author:junlin.ru
 * @Date:2021/7/27 11:11
 **/
public class RedisUtils {

    private RedisTemplate<String, Object> redisTemplate;

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public RedisTemplate<String, Object> getRedisTemplate(){
        return this.redisTemplate;
    }

    /** -------------------key相关操作--------------------- */

    /**
     * 删除指定的一批keys,如果删除中的某些key不存在,则直接忽略。
     * @param key 需要删除的key值
     * @return  true-成功  false-失败
     */
    public Boolean del(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 删除指定的一批keys,如果删除中的某些key不存在,则直接忽略。
     * @param keys 需要删除的多个key值(集合)
     * @return 实际删除个数
     */
    public Long del(Collection<String> keys) {
        return redisTemplate.delete(keys);
    }

    /**
     * 序列化给定 key ,并返回被序列化的值 使用 RESTORE 命令可以将这个值反序列化为 Redis 键。
     *
     * 序列化生成的值有以下几个特点:
     * 1、它带有 64 位的校验和,用于检测错误,RESTORE 在进行反序列化之前会先检查校验和。
     * 2、值的编码格式和 RDB 文件保持一致。
     * 3、RDB 版本会被编码在序列化值当中,如果因为 Redis 的版本不同造成 RDB 格式不兼容,那么 Redis 会拒绝对这个值进行反序列化操作。
     * 4、序列化的值不包括任何生存时间信息。
     *
     * @param key key值
     * @return 序列化字节数组 (如果 key 不存在,那么返回 null,需要做判空处理 否则,返回序列化之后的值)
     */
    public byte[] dump(String key) {
        return redisTemplate.dump(key);
    }

    /**
     * 反序列化给定的序列化值,并将它和给定的 key 关联。
     *
     * @param key key值
     * @param value 序列化数组
     * @param timeout 生存时间,为0时认为不设置超时时间
     * @param unit  时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     */
    public void restore(String key, byte[] value,long timeout, TimeUnit unit){
        redisTemplate.restore(key, value, timeout,unit);
    }

    /**
     * 反序列化给定的序列化值,并将它和给定的 key 关联。
     *
     * @param key key值
     * @param value 序列化数组
     * @param timeout 生存时间,为0时认为不设置超时时间
     * @param unit  时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     * @param replace true-替代存在的redis  false-不替代存在的key
     */
    public void restore(String key, byte[] value,long timeout, TimeUnit unit,Boolean replace){
        redisTemplate.restore(key, value, timeout,unit, replace);
    }

    /**
     * 是否存在key
     *
     * @param key key值
     * @return true-存在  false-不存在
     */
    public Boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 设置过期时间
     *
     * @param key key值
     * @param timeout 超时时间
     * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     * @return true-成功  false-失败
     */
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 设置过期时间
     *
     * @param key key值
     * @param date 超时日期
     * @return true-成功  false-失败
     */
    public Boolean expireAt(String key, Date date) {
        return redisTemplate.expireAt(key, date);
    }

    /**
     * 查找所有符合给定模式pattern(正则表达式)的 key 。
     * 时间复杂度为O(N),N为数据库里面key的数量。
     *
     * 例如,Redis在一个有1百万个key的数据库里面执行一次查询需要的时间是40毫秒 。
     *
     * 警告: KEYS 的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 KEYS, 你最好还是用 Redis 的集合结构 SETS 来代替。
     *
     * 支持的正则表达模式:
     * h?llo 匹配 hello, hallo 和 hxllo
     * h*llo 匹配 hllo 和 heeeello
     * h[ae]llo 匹配 hello 和 hallo, 但是不匹配 hillo
     * h[^e]llo 匹配 hallo, hbllo, … 但是不匹配 hello
     * h[a-b]llo 匹配 hallo 和 hbllo
     * 如果你想取消字符的特殊匹配(正则表达式,可以在它的前面加\。
     *
     * @param pattern 正则表达
     * @return 所有符合条件的key
     */
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * 将当前数据库的 key 移动到给定的数据库 db 当中
     * 如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。
     *
     * @param key key值
     * @param dbIndex 指定数据库db
     * @return true-成功  false-失败
     */
    public Boolean move(String key, int dbIndex) {
        return redisTemplate.move(key, dbIndex);
    }

    /**
     * 移除 key 的过期时间,key 将持久保持
     *
     * @param key key值
     * @return true-成功  false-失败
     */
    public Boolean persist(String key) {
        return redisTemplate.persist(key);
    }

    /**
     * 返回 key 的剩余的过期时间
     *
     * @param key key值
     * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     * @return 返回的过期时长
     */
    public Long getExpire(String key, TimeUnit unit) {
        return redisTemplate.getExpire(key, unit);
    }

    /**
     * 返回 key 的剩余的过期时间
     *
     * @param key key值
     * @return 返回的过期时长
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 从当前数据库中随机返回一个 key
     *
     * @return 随机key 没有则返回null
     */
    public String randomKey() {
        return redisTemplate.randomKey();
    }

    /**
     * 修改 key 的名称
     *
     * @param oldKey 旧的keyName
     * @param newKey  新的keyName
     */
    public void rename(String oldKey, String newKey) {
        redisTemplate.rename(oldKey, newKey);
    }

    /**
     * 仅当 newkey 不存在时,将 oldKey 改名为 newkey
     *
     * @param oldKey 旧的keyName
     * @param newKey 新的keyName
     * @return true-成功  false-失败
     */
    public Boolean renameIfAbsent(String oldKey, String newKey) {
        return redisTemplate.renameIfAbsent(oldKey, newKey);
    }

    /**
     * 返回 key 所储存的值的类型
     *
     * @param key key值
     * @return 值的类型
     */
    public DataType type(String key) {
        return redisTemplate.type(key);
    }

    /** -------------------string相关操作--------------------- */

    /**
     * 如果 key 已经存在,并且值为字符串,那么这个命令会把 value 追加到原来值(value)的结尾。 如果 key 不存在,那么它将首先创建一个空字符串的key,再执行追加操作
     *
     * @param key key值
     * @param value value值
     * @return 返回append后字符串值(value)的长度
     */
    public Integer append(String key, String value) {
        return redisTemplate.opsForValue().append(key, value);
    }


    /**
     * 设置指定 key 的值
     * @param key key值
     * @param value value值
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 获取指定 key 的值
     * @param key key值
     * @return  value值
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 返回 key 中字符串值的子字符
     * 可以用负的位移来表示从string尾部开始数的下标。所以-1就是最后一个字符,-2就是倒数第二个,以此类
     * @param key key值
     * @param start 开始位置
     * @param end 结束位置
     * @return 返回key对应的字符串value的子串
     */
    public String getRange(String key, long start, long end) {
        return redisTemplate.opsForValue().get(key, start, end);
    }

    /**
     * 自动将key对应到value并且返回原来key对应的value。如果key存在但是对应的value不是字符串(string),就返回错误。
     *
     * 设计模式
     * GETSET可以和INCR一起使用实现支持重置的计数功能。
     *
     *
     * @param key key值
     * @param value value值
     * @return 旧value值
     */
    public Object getAndSet(String key, String value) {
        return redisTemplate.opsForValue().getAndSet(key, value);
    }

    /**
     * 设置ASCII码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第offset位值变为value
     *
     * 设计模式:可setBit与getBit组合可应用于业务统计某用户是否做了某事,例如统计近7天某用于是否都登录等
     *
     * @param key key值
     * @param offset 位置
     * @param value 值,true为1, false为0
     * @return  true-成功  false-失败
     */
    public boolean setBit(String key, long offset, boolean value) {
        return redisTemplate.opsForValue().setBit(key, offset, value);
    }

    /**
     * 对 key 所储存的字符串值,获取指定偏移量上的位(bit)
     *
     * 设计模式:可setBit与getBit组合可应用于业务统计某用户是否做了某事,例如统计近7天某用于是否都登录等、签到、浏览记录等
     *
     * @param key key值
     * @param offset
     * @return
     */
    public Boolean getBit(String key, long offset) {
        return redisTemplate.opsForValue().getBit(key, offset);
    }

    /**
     * 批量获取
     * 对于每个不对应string或者不存在的key,都返回特殊值null
     * @param keys key集合列表
     * @return 指定的key对应的values的list
     */
    public List<Object> multiGet(Collection<String> keys) {
        return redisTemplate.opsForValue().multiGet(keys);
    }

    /**
     * 批量添加
     * 对应给定的keys到他们相应的values上。MSET会用新的value替换已经存在的value
     * @param maps 一个或多个 key-value
     */
    public void multiSet(Map<String, Object> maps) {
        redisTemplate.opsForValue().multiSet(maps);
    }

    /**
     * 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
     *
     * @param maps 一个或多个 key-value
     * @return 之前已经存在返回false,不存在返回true
     */
    public boolean multiSetIfAbsent(Map<String, String> maps) {
        return redisTemplate.opsForValue().multiSetIfAbsent(maps);
    }

    /**
     * 将值 value 关联到 key ,并将 key 的过期时间设为 timeout
     *
     * @param key key值
     * @param value value值
     * @param timeout 过期时间
     * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     */
    public void setEx(String key, String value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    /**
     * 将key设置值为value,如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做
     *
     * @param key key值
     * @param value value值
     * @return 之前已经存在返回false,不存在返回true
     */
    public boolean setIfAbsent(String key, String value) {
        return redisTemplate.opsForValue().setIfAbsent(key, value);
    }


    /**
     * 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
     *
     * @param key key值
     * @param value value值
     * @param offset 从指定位置开始覆写  offset最大可以是229-1(536870911),因为redis字符串限制在512M大小。如果你需要超过这个大小,你可以用多个keys
     */
    public void setRange(String key, String value, long offset) {
        redisTemplate.opsForValue().set(key, value, offset);
    }

    /**
     * 返回key的string类型value的长度。如果key对应的非string类型,就返回错误
     *
     * @param key key值
     * @return 字符串的长度
     */
    public Long size(String key) {
        return redisTemplate.opsForValue().size(key);
    }


    /**
     * 将key对应的数字加decrement。如果key不存在,操作之前,key就会被置为0。如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误
     * 增加(自增长), 负数则为自减
     *
     * @param key key值
     * @param increment 自增/自减数
     * @return 增加之后的value值
     */
    public Long incrBy(String key, long increment) {
        return redisTemplate.opsForValue().increment(key, increment);
    }

    /**
     * (浮点型)将key对应的数字加decrement。如果key不存在,操作之前,key就会被置为0。如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误
     * @param key key值
     * @param increment 自增/自减数
     * @return 增加之后的value值
     */
    public Double incrByFloat(String key, double increment) {
        return redisTemplate.opsForValue().increment(key, increment);
    }


    /** -------------------hash相关操作------------------------- */

    /**
     * 获取存储在哈希表中指定字段的值
     *
     * 返回 key 指定的哈希集中该字段所关联的值
     *
     * @param key key值
     * @param field 指定字段的值
     * @return field值对应value值
     */
    public Object hGet(String key, String field) {
        return redisTemplate.opsForHash().get(key, field);
    }

    /**
     * 获取所有给定字段的值
     *
     * @param key  key值
     * @return 获取key中的所有field对应的value (键值对)
     */
    public Map<Object, Object> hGetAll(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 获取所有给定字段的值
     *
     * @param key key值
     * @param fields 指定字段的值
     * @return 获取key中的指定多个field对应的value(列表)
     */
    public List<Object> hMultiGet(String key, Collection<Object> fields) {
        return redisTemplate.opsForHash().multiGet(key, fields);
    }

    /**
     * 设置 key 指定的哈希集中指定字段的值
     *
     * 如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。
     *
     * 如果字段在哈希集中存在,它将被重写。
     *
     * @param key key值
     * @param hashKey field值
     * @param value field值对应value值
     */
    public void hPut(String key, String hashKey, String value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    /**
     * 设置 key 指定的哈希集中多个字段的值
     *
     * 如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。
     *
     * 如果字段在哈希集中存在,它将被重写。
     *
     * @param key key值
     * @param maps field对应value的map
     */
    public void hPutAll(String key, Map<String, String> maps) {
        redisTemplate.opsForHash().putAll(key, maps);
    }

    /**
     * 仅当hashKey不存在时才设置
     *
     * 只在 key 指定的哈希集中不存在指定的字段时,设置字段的值。
     * 如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。如果字段已存在,该操作无效果。
     *
     * @param key key值
     * @param hashKey field值
     * @param value field值对应value值
     * @return true-成功  false-失败
     */
    public Boolean hPutIfAbsent(String key, String hashKey, String value) {
        return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
    }

    /**
     * 删除一个或多个哈希表字段
     *
     * 从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。
     *
     * 如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0。
     *
     * @param key key值
     * @param fields 一个或多个哈希表字段
     * @return 返回从哈希集中成功移除的域的数量,不包括指出但不存在的那些域
     */
    public Long hDelete(String key, Object... fields) {
        return redisTemplate.opsForHash().delete(key, fields);
    }

    /**
     * 查看哈希表 key 中,指定的字段是否存在
     * 返回hash里面field是否存在
     *
     * @param key key值
     * @param field 指定field值
     * @return true-存在  false-不存在
     */
    public boolean hExists(String key, String field) {
        return redisTemplate.opsForHash().hasKey(key, field);
    }

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * 增加 key 指定的哈希集中指定字段的数值。如果 key 不存在,会创建一个新的哈希集并与 key 关联。如果字段不存在,则字段的值在该操作执行前被设置为 0
     *
     * @param key key值
     * @param field 指定field值
     * @param increment 增量
     * @return 增值操作执行后的该字段的值
     */
    public Long hIncrBy(String key, Object field, long increment) {
        return redisTemplate.opsForHash().increment(key, field, increment);
    }

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * 为指定key的hash的field字段值执行float类型的increment加。如果field不存在,则在执行该操作前设置为0.如果出现下列情况之一,则返回错误:
     *
     * field的值包含的类型错误(不是字符串)。
     * 当前field或者increment不能解析为一个float类型。
     *
     * @param key key值
     * @param field 指定field值
     * @param delta 增量
     * @return field执行increment加后的值
     */
    public Double hIncrByFloat(String key, Object field, double delta) {
        return redisTemplate.opsForHash().increment(key, field, delta);
    }

    /**
     * 获取所有哈希表中的字段
     *
     * @param key key值
     * @return 所有哈希表中的字段(该key的所有field值) 哈希集中的字段列表,当 key 指定的哈希集不存在时返回空列表
     */
    public Set<Object> hKeys(String key) {
        return redisTemplate.opsForHash().keys(key);
    }

    /**
     * 获取哈希表中字段的数量
     *
     * @param key key值
     * @return  哈希表中字段field的数量
     */
    public Long hSize(String key) {
        return redisTemplate.opsForHash().size(key);
    }

    /**
     * 获取哈希表中所有值
     *
     * @param key key值
     * @return 哈希表中所有field对应的value值
     */
    public List<Object> hValues(String key) {
        return redisTemplate.opsForHash().values(key);
    }

    /**
     * 迭代哈希表中的键值对
     *
     * @param key key值
     * @param options
     * @return
     */
    public Cursor<Map.Entry<Object, Object>> hScan(String key, ScanOptions options) {
        return redisTemplate.opsForHash().scan(key, options);
    }

    /** ------------------------list相关操作---------------------------- */

    /**
     * 通过索引获取列表中的元素
     * 返回列表里的元素的索引 index 存储在 key 里面。 下标是从0开始索引的,所以 0 是表示第一个元素, 1 表示第二个元素,并以此类推。 负数索引用于指定从列表尾部开始索引的元素。在这种方法下,-1 表示最后一个元素,-2 表示倒数第二个元素,并以此往前推。
     * 当 key 位置的值不是一个列表的时候,会返回一个error
     *
     * @param key key值
     * @param index  索引
     * @return value值
     */
    public Object lIndex(String key, long index) {
        return redisTemplate.opsForList().index(key, index);
    }

    /**
     * 返回存储在 key 的列表里指定范围内的元素。 start 和 end 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推。
     * 偏移量也可以是负数,表示偏移量是从list尾部开始计数。 例如, -1 表示列表的最后一个元素,-2 是倒数第二个,以此类推。
     * 注意:当下标超过list范围的时候不会产生error。 如果start比list的尾部下标大的时候,会返回一个空列表。 如果stop比list的实际尾部大的时候,Redis会当它是最后一个元素的下标。
     * @param key key值
     * @param start 开始位置, 0是开始位置
     * @param end 结束位置, -1返回所有
     * @return 指定范围里的列表元素
     */
    public List<Object> lRange(String key, long start, long end) {
        return redisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么在进行 push 操作前会创建一个空列表。
     * 如果 key 对应的值不是一个 list 的话,那么会返回一个错误。
     *
     *
     * @param key key值
     * @param value value值
     * @return  push 操作后的 list 长度
     */
    public Long lLeftPush(String key, String value) {
        return redisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * 可以使用一个命令把多个元素 push 进入列表,只需在命令末尾加上多个指定的参数。
     * 元素是从最左端的到最右端的、一个接一个被插入到 list 的头部。
     * 所以对于这个命令例子 LPUSH mylist a b c,返回的列表是 c 为第一个元素, b 为第二个元素, a 为第三个元素。
     * @param key key值
     * @param value value值
     * @return push 操作后的 list 长度
     */
    public Long lLeftPushAll(String key, String... value) {
        return redisTemplate.opsForList().leftPushAll(key, value);
    }

    /**
     * 可以使用一个命令把多个元素 push 进入列表,只需在命令末尾加上多个指定的参数。
     * 元素是从最左端的到最右端的、一个接一个被插入到 list 的头部。
     * 所以对于这个命令例子 LPUSH mylist a b c,返回的列表是 c 为第一个元素, b 为第二个元素, a 为第三个元素。
     * @param key key值
     * @param value value值(集合)
     * @return push 操作后的 list 长度
     */
    public Long lLeftPushAll(String key, Collection<String> value) {
        return redisTemplate.opsForList().leftPushAll(key, value);
    }

    /**
     * 当list存在的时候才加入
     * 只有当 key 已经存在并且存着一个 list 的时候,在这个 key 下面的 list 的头部插入 value。 与 LPUSH 相反,当 key 不存在的时候不会进行任何操作。
     * @param key key值
     * @param value value值
     * @return push 操作后的 list 长度
     */
    public Long lLeftPushIfPresent(String key, String value) {
        return redisTemplate.opsForList().leftPushIfPresent(key, value);
    }

    /**
     * 如果pivot存在,再pivot前面添加
     * 把 value 插入存于 key 的列表中在基准值 pivot 的前面。
     * 当 key 不存在时,这个list会被看作是空list,任何操作都不会发生。
     * 当 key 存在,但保存的不是一个list的时候,会返回error
     *
     * @param key key值
     * @param pivot BEFORE
     * @param value value值
     * @return 经过插入操作后的list长度,或者当 pivot 值找不到的时候返回 -1
     */
    public Long lLeftPush(String key, String pivot, String value) {
        return redisTemplate.opsForList().leftPush(key, pivot, value);
    }

    /**
     * 向存于 key 的列表的尾部插入所有指定的值。如果 key 不存在,那么会创建一个空的列表然后再进行 push 操作。
     * 当 key 保存的不是一个列表,那么会返回一个错误
     *
     * @param key key值
     * @param value value值
     * @return  push 操作后的列表长度
     */
    public Long lRightPush(String key, String value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 可以使用一个命令把多个元素打入队列,只需要在命令后面指定多个参数。元素是从左到右一个接一个从列表尾部插入。
     * 比如命令 RPUSH mylist a b c 会返回一个列表,其第一个元素是 a ,第二个元素是 b ,第三个元素是 c
     *
     * @param key key值
     * @param value value值
     * @return push 操作后的列表长度
     */
    public Long lRightPushAll(String key, String... value) {
        return redisTemplate.opsForList().rightPushAll(key, value);
    }

    /**
     *  可以使用一个命令把多个元素打入队列,只需要在命令后面指定多个参数。元素是从左到右一个接一个从列表尾部插入。
     *  比如命令 RPUSH mylist a b c 会返回一个列表,其第一个元素是 a ,第二个元素是 b ,第三个元素是 c
     *
     * @param key key值
     * @param value value值 (集合)
     * @return push 操作后的列表长度
     */
    public Long lRightPushAll(String key, Collection<String> value) {
        return redisTemplate.opsForList().rightPushAll(key, value);
    }

    /**
     * 将值 value 插入到列表 key 的表尾, 当且仅当 key 存在并且是一个列表。 和 RPUSH 命令相反, 当 key 不存在时,RPUSHX 命令什么也不做
     *
     * @param key key值
     * @param value value值
     * @return 命令执行之后,表的长度
     */
    public Long lRightPushIfPresent(String key, String value) {
        return redisTemplate.opsForList().rightPushIfPresent(key, value);
    }

    /**
     * 在pivot元素的右边添加值
     * 把 value 插入存于 key 的列表中在基准值 pivot 的后面。
     * 当 key 不存在时,这个list会被看作是空list,任何操作都不会发生。
     * 当 key 存在,但保存的不是一个list的时候,会返回error
     *
     * @param key  key值
     * @param pivot pivot元素
     * @param value value值
     * @return 经过插入操作后的list长度,或者当 pivot 值找不到的时候返回 -1
     */
    public Long lRightPush(String key, String pivot, String value) {
        return redisTemplate.opsForList().rightPush(key, pivot, value);
    }

    /**
     * 通过索引设置列表元素的值
     * 设置 index 位置的list元素的值为 value
     * 当index超出范围时会返回一个error
     *
     * @param key key值
     * @param index 索引位置
     * @param value value值
     */
    public void lSet(String key, long index, String value) {
        redisTemplate.opsForList().set(key, index, value);
    }

    /**
     * 移除并且返回 key 对应的 list 的第一个元素
     *
     * @param key key值
     * @return 返回第一个元素的值,或者当 key 不存在时返回 nil
     */
    public Object lLeftPop(String key) {
        return redisTemplate.opsForList().leftPop(key);
    }

    /**
     * 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param key key值
     * @param timeout 等待时间
     * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     * @return 当没有元素的时候会弹出一个 nil 的多批量值,并且 timeout 过期。
     * 当有元素弹出时会返回一个双元素的多批量值,其中第一个元素是弹出元素的 key,第二个元素是 value。
     */
    public Object lBLeftPop(String key, long timeout, TimeUnit unit) {
        return redisTemplate.opsForList().leftPop(key, timeout, unit);
    }

    /**
     * 移除并返回存于 key 的 list 的最后一个元素
     *
     * @param key key值
     * @return 最后一个元素的值,或者当 key 不存在的时候返回 null
     */
    public Object lRightPop(String key) {
        return redisTemplate.opsForList().rightPop(key);
    }

    /**
     * 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param key key值
     * @param timeout 等待时间
     * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     * @return 当没有元素可以被弹出时返回一个 nil 的多批量值,并且 timeout 过期。
     * 当有元素弹出时会返回一个双元素的多批量值,其中第一个元素是弹出元素的 key,第二个元素是 value
     *
     */
    public Object lBRightPop(String key, long timeout, TimeUnit unit) {
        return redisTemplate.opsForList().rightPop(key, timeout, unit);
    }

    /**
     * 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
     * 原子性地返回并移除存储在 source 的列表的最后一个元素(列表尾部元素), 并把该元素放入存储在 destination 的列表的第一个元素位置(列表头部)
     *
     * @param sourceKey 被移除的key值
     * @param destinationKey 移除到的key值
     * @return 被移除和放入的元素
     */
    public Object lRightPopAndLeftPush(String sourceKey, String destinationKey) {
        return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
                destinationKey);
    }

    /**
     * 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     * 原子性地返回并移除存储在 source 的列表的最后一个元素(列表尾部元素), 并把该元素放入存储在 destination 的列表的第一个元素位置(列表头部)(阻塞版)
     *
     * @param sourceKey 被移除的key值
     * @param destinationKey 移除到的key值
     * @param timeout 等待时间
     * @param unit 时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
     * @return 元素从 source 中弹出来,并压入 destination 中。 如果达到 timeout 时限,会返回一个空的多批量回复(nil-reply)
     */
    public Object lBRightPopAndLeftPush(String sourceKey, String destinationKey,
                                        long timeout, TimeUnit unit) {
        return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey,
                destinationKey, timeout, unit);
    }

    /**
     * 删除集合中值等于value得元素
     *
     * @param key key值
     * @param index
     *            index=0, 删除所有值等于value的元素;
     *            index>0, 从头部开始删除第一个值等于value的元素;
     *            index<0, 从尾部开始删除第一个值等于value的元素;
     * @param value value值
     * @return 被移除的元素个数
     */
    public Long lRemove(String key, long index, String value) {
        return redisTemplate.opsForList().remove(key, index, value);
    }

    /**
     * 裁剪list
     * start 和 stop 都是由0开始计数的, 这里的 0 是列表里的第一个元素(表头),1 是第二个元素,以此类推
     * start 和 end 也可以用负数来表示与表尾的偏移量,比如 -1 表示列表里的最后一个元素, -2 表示倒数第二个
     * @param key key值
     * @param start 开始索引
     * @param end 结束索引
     */
    public void lTrim(String key, long start, long end) {
        redisTemplate.opsForList().trim(key, start, end);
    }

    /**
     * 返回存储在 key 里的list的长度。 如果 key 不存在,那么就被看作是空list,并且返回长度为 0。 当存储在 key 里的值不是一个list的话,会返回error
     *
     * @param key key值
     * @return key对应的list的长度
     */
    public Long lLen(String key) {
        return redisTemplate.opsForList().size(key);
    }

    /** --------------------set相关操作-------------------------- */

    /**
     * set添加元素
     * 添加一个或多个指定的member元素到集合的 key中.
     * 指定的一个或者多个元素member 如果已经在集合key中存在则忽略.如果集合key 不存在,则新建集合key,并添加member元素到集合key中.
     *
     * 如果key 的类型不是集合则返回错误
     *
     * @param key key值
     * @param values values值
     * @return 返回新成功添加到集合里元素的数量,不包括已经存在于集合中的元素.
     */
    public Long sAdd(String key, String... values) {
        return redisTemplate.opsForSet().add(key, values);
    }

    /**
     * set移除元素
     * 在key集合中移除指定的元素. 如果指定的元素不是key集合中的元素则忽略 如果key集合不存在则被视为一个空的集合,该命令返回0.
     *
     * 如果key的类型不是一个集合,则返回错误.
     *
     * @param key key值
     * @param values  移除指定的元素
     * @return 从集合中移除元素的个数,不包括不存在的成员
     */
    public Long sRemove(String key, Object... values) {
        return redisTemplate.opsForSet().remove(key, values);
    }

    /**
     * 移除并返回集合的一个随机元素
     * 从存储在key的集合中移除并返回一个或多个随机元素。
     *
     * 此操作与SRANDMEMBER类似,它从一个集合中返回一个或多个随机元素,但不删除元素。
     *
     * count参数将在更高版本中提供,但是在2.6、2.8、3.0中不可用
     *
     * @param key key值
     * @return 被删除的元素,或者当key不存在时返回null
     */
    public Object sPop(String key) {
        return redisTemplate.opsForSet().pop(key);
    }

    /**
     * 将元素value从一个集合移到另一个集合
     *
     * 将member从source集合移动到destination集合中. 对于其他的客户端,在特定的时间元素将会作为source或者destination集合的成员出现.
     *
     * 如果source 集合不存在或者不包含指定的元素,这smove命令不执行任何操作并且返回0.否则对象将会从source集合中移除,并添加到destination集合中去,
     * 如果destination集合已经存在该元素,则smove命令仅将该元素充source集合中移除. 如果source 和destination不是集合类型,则返回错误
     *
     * @param key source集合(源集合)
     * @param value  value 指定元素
     * @param destKey destination集合(目标集合)
     * @return true-成功  false-失败
     */
    public Boolean sMove(String key, String value, String destKey) {
        return redisTemplate.opsForSet().move(key, value, destKey);
    }

    /**
     * 获取集合的大小
     *
     * 返回集合存储的key的基数 (集合元素的数量).
     *
     * @param key key值
     * @return 集合的基数(元素的数量),如果key不存在,则返回 0.
     */
    public Long sSize(String key) {
        return redisTemplate.opsForSet().size(key);
    }

    /**
     * 判断集合是否包含value
     *  返回成员 member 是否是存储的集合 key的成员.
     *
     * @param key key值
     * @param value member成员
     * @return
     *        如果member元素是集合key的成员,则返回1
     *        如果member元素不是key的成员,或者集合key不存在,则返回0
     */
    public Boolean sIsMember(String key, Object value) {
        return redisTemplate.opsForSet().isMember(key, value);
    }

    /**
     * 获取两个集合的交集
     *
     * 返回指定所有的集合的成员的交集
     *
     * @param key key值
     * @param otherKey 另外一个集合key
     * @return 交集
     */
    public Set<Object> sIntersect(String key, String otherKey) {
        return redisTemplate.opsForSet().intersect(key, otherKey);
    }

    /**
     * 获取key集合与多个集合的交集
     *
     * @param key key值
     * @param otherKeys 多个集合key
     * @return 交集
     */
    public Set<Object> sIntersect(String key, Collection<String> otherKeys) {
        return redisTemplate.opsForSet().intersect(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的交集存储到destKey集合中
     *
     * 如果destKey集合存在, 则会被重写
     *
     * @param key key值
     * @param otherKey otherKey集合
     * @param destKey destKey集合(目标存储集合key)
     * @return  交集结果集中成员的个数
     */
    public Long sIntersectAndStore(String key, String otherKey, String destKey) {
        return redisTemplate.opsForSet().intersectAndStore(key, otherKey,
                destKey);
    }

    /**
     * key集合与多个集合的交集存储到destKey集合中
     *
     * 如果destKey集合存在, 则会被重写
     *
     * @param key key值
     * @param otherKeys 多个otherKey集合
     * @param destKey destKey集合(目标存储集合key)
     * @return 交集结果集中成员的个数
     */
    public Long sIntersectAndStore(String key, Collection<String> otherKeys,
                                   String destKey) {
        return redisTemplate.opsForSet().intersectAndStore(key, otherKeys,
                destKey);
    }

    /**
     * 获取两个集合的并集
     *
     * 返回给定的多个集合的并集中的所有成员.
     *
     * @param key key值
     * @param otherKeys otherKey集合
     * @return 并集
     */
    public Set<Object> sUnion(String key, String otherKeys) {
        return redisTemplate.opsForSet().union(key, otherKeys);
    }

    /**
     * 获取key集合与多个集合的并集
     *
     * @param key key值
     * @param otherKeys 多个otherKey集合
     * @return 并集
     */
    public Set<Object> sUnion(String key, Collection<String> otherKeys) {
        return redisTemplate.opsForSet().union(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的并集存储到destKey中
     *
     * 如果destKey集合存在, 则会被重写
     *
     * @param key key值
     * @param otherKey otherKey集合
     * @param destKey destKey集合(目标存储集合key)
     * @return 并集结果集中元素的个数
     */
    public Long sUnionAndStore(String key, String otherKey, String destKey) {
        return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
    }

    /**
     * key集合与多个集合的并集存储到destKey中
     *
     * 如果destKey集合存在, 则会被重写
     *
     * @param key key值
     * @param otherKeys 多个otherKey集合
     * @param destKey destKey集合(目标存储集合key)
     * @return 并集结果集中元素的个数
     */
    public Long sUnionAndStore(String key, Collection<String> otherKeys,
                               String destKey) {
        return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey);
    }

    /**
     * 获取两个集合的差集
     *
     * 不存在的key认为是空集
     *
     * @param key key值
     * @param otherKey otherKey集合
     * @return 差集
     */
    public Set<Object> sDifference(String key, String otherKey) {
        return redisTemplate.opsForSet().difference(key, otherKey);
    }

    /**
     * 获取key集合与多个集合的差集
     *
     * 不存在的key认为是空集
     *
     * @param key key值
     * @param otherKeys 多个otherKey集合
     * @return 差集
     */
    public Set<Object> sDifference(String key, Collection<String> otherKeys) {
        return redisTemplate.opsForSet().difference(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的差集存储到destKey中
     *
     * 如果destKey集合存在, 则会被重写
     *
     * @param key key值
     * @param otherKey otherKey集合
     * @param destKey destKey集合(目标存储集合key)
     * @return 差集结果集元素的个数
     */
    public Long sDifference(String key, String otherKey, String destKey) {
        return redisTemplate.opsForSet().differenceAndStore(key, otherKey,
                destKey);
    }

    /**
     * key集合与多个集合的差集存储到destKey中
     *
     * 如果destKey集合存在, 则会被重写
     *
     * @param key key值
     * @param otherKeys 多个otherKey集合
     * @param destKey destKey集合(目标存储集合key)
     * @return 差集结果集元素的个数
     */
    public Long sDifference(String key, Collection<String> otherKeys,
                            String destKey) {
        return redisTemplate.opsForSet().differenceAndStore(key, otherKeys,
                destKey);
    }

    /**
     * 获取集合所有元素
     *
     * 返回key集合所有的元素.
     *
     * @param key key值
     * @return 集合中的所有元素
     */
    public Set<Object> setMembers(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * 随机获取集合中的一个元素
     *
     * @param key key值
     * @return 返回随机的元素,如果key不存在则返回null。
     */
    public Object sRandomMember(String key) {
        return redisTemplate.opsForSet().randomMember(key);
    }

    /**
     * 随机获取集合中count个元素
     *
     * @param key key值
     * @param count
     *              如果count是整数且小于元素的个数,返回含有 count 个不同的元素的数组,
     *              如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,当count是负数,则会返回一个包含count的绝对值的个数元素的数组,
     *              如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.
     * @return 返回一个随机的元素数组,如果key不存在则返回一个空的数组
     */
    public List<Object> sRandomMembers(String key, long count) {
        return redisTemplate.opsForSet().randomMembers(key, count);
    }

    /**
     * 随机获取集合中count个元素并且去除重复的
     *
     * @param key key值
     * @param count
     *              如果count是整数且小于元素的个数,返回含有 count 个不同的元素的数组,
     *              如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,当count是负数,则会返回一个包含count的绝对值的个数元素的数组,
     *              如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.
     * @return 返回一个随机的元素数组,如果key不存在则返回一个空的数组
     */
    public Set<Object> sDistinctRandomMembers(String key, long count) {
        return redisTemplate.opsForSet().distinctRandomMembers(key, count);
    }

    /**
     *
     * @param key
     * @param options
     * @return
     */
    public Cursor<Object> sScan(String key, ScanOptions options) {
        return redisTemplate.opsForSet().scan(key, options);
    }

    /**------------------zSet相关操作--------------------------------*/

    /**
     * 添加元素,有序集合是按照元素的score值由小到大排列
     * (单个添加)
     * @param key key值
     * @param value value值
     * @param score 分数
     * @return 是否成果
     */
    public Boolean zAdd(String key, String value, double score) {
        return redisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     * 添加元素,有序集合是按照元素的score值由小到大排列
     *  (多个添加)
     * @param key key值
     * @param values value与score的TypedTuple
     * @return 添加到有序集合的成员数量
     */
    public Long zAdd(String key, Set<TypedTuple<Object>> values) {
        return redisTemplate.opsForZSet().add(key, values);
    }

    /**
     * 移除有序集合中的value
     * 注意:当key存在,但是其不是有序集合类型,就返回一个错误。
     * @param key key值
     * @param values value值
     * @return 从有序集合中删除的成员个数,不包括不存在的成员
     */
    public Long zRemove(String key, Object... values) {
        return redisTemplate.opsForZSet().remove(key, values);
    }

    /**
     * 增加元素的score值,并返回增加后的值
     *
     * 为有序集key的成员member的score值加上增量increment。如果key中不存在member,就在key中添加一个member,score是increment(就好像它之前的score是0.0)。
     * 如果key不存在,就创建一个只含有指定member成员的有序集合。
     *
     * 当key不是有序集类型时,返回一个错误。
     *
     * score值必须是字符串表示的整数值或双精度浮点数,并且能接受double精度的浮点数。也有可能给一个负数来减少score的值。
     *
     * @param key key值
     * @param value value值
     * @param delta 增量
     * @return member成员的新score值
     */
    public Double zIncrementScore(String key, String value, double delta) {
        return redisTemplate.opsForZSet().incrementScore(key, value, delta);
    }

    /**
     * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
     *
     * @param key key值
     * @param value value值
     * @return 0表示第一位(score值最小的成员排名为0)
     */
    public Long zRank(String key, Object value) {
        return redisTemplate.opsForZSet().rank(key, value);
    }

    /**
     * 返回元素在集合的排名,按元素的score值由大到小排列
     *
     * @param key key值
     * @param value value值
     * @return 0表示第一位(score值最大的成员排名为0)
     */
    public Long zReverseRank(String key, Object value) {
        return redisTemplate.opsForZSet().reverseRank(key, value);
    }

    /**
     * 获取集合的元素, 从小到大排序
     *
     * @param key key值
     * @param start 开始位置
     * @param end 结束位置, -1查询所有
     * @return 返回value
     */
    public Set<Object> zRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().range(key, start, end);
    }

    /**
     * 获取集合元素, 并且把score值也获取  从小到大排序
     * @param key key值
     * @param start  开始位置
     * @param end 结束位置, -1查询所有
     * @return 返回value与score
     */
    public Set<TypedTuple<Object>> zRangeWithScores(String key, long start, long end) {
        return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }

    /**
     * 根据Score值查询集合元素
     *
     * @param key key值
     * @param min score小值
     * @param max score最大值
     * @return 返回value(从小到大)
     */
    public Set<Object> zRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }

    /**
     * 根据Score值查询集合元素, 从小到大排序
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @return 返回value与score(从小到大)
     */
    public Set<TypedTuple<Object>> zRangeByScoreWithScores(String key, double min, double max) {
        return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
    }

    /**
     * 根据Score值查询集合元素, 从小到大排序
     *
     * 可选的LIMIT参数指定返回结果的数量及区间(类似SQL中SELECT LIMIT offset, count)
     * 如果offset太大,定位offset就可能遍历整个有序集合,这会增加O(N)的复杂度。
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @param start offset
     * @param end count
     * @return 返回value与score(从小到大)
     */
    public Set<TypedTuple<Object>> zRangeByScoreWithScores(String key, double min, double max, long start, long end) {
        return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, start, end);
    }

    /**
     * 获取集合的元素, 从大到小排序
     *
     * @param key key值
     * @param start 开始位置
     * @param end 结束位置, -1查询所有
     * @return 返回value
     */
    public Set<Object> zReverseRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().reverseRange(key, start, end);
    }

    /**
     * 获取集合的元素, 从大到小排序, 并返回score值
     *
     * @param key key值
     * @param start 开始位置
     * @param end 结束位置, -1查询所有
     * @return 返回value
     */
    public Set<TypedTuple<Object>> zReverseRangeWithScores(String key, long start, long end) {
        return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
    }

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @return 返回value(从大到小)
     */
    public Set<Object> zReverseRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
    }

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @return  返回value与score(从大到小)
     */
    public Set<TypedTuple<Object>> zReverseRangeByScoreWithScores(String key, double min, double max) {
        return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max);
    }

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * 可选的LIMIT参数指定返回结果的数量及区间(类似SQL中SELECT LIMIT offset, count)
     * 如果offset太大,定位offset就可能遍历整个有序集合,这会增加O(N)的复杂度。
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @param start offset
     * @param end count
     * @return 返回value与score(从大到小)
     */
    public Set<Object> zReverseRangeByScore(String key, double min, double max, long start, long end) {
        return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end);
    }

    /**
     * 根据score值区间获取集合元素数量
     *
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @return 指定分数范围的元素个数。
     */
    public Long zCount(String key, double min, double max) {
        return redisTemplate.opsForZSet().count(key, min, max);
    }


    /**
     * 获取集合大小
     * key存在的时候,返回有序集的元素个数,否则返回0
     * @param key key值
     * @return 集合大小
     */
    public Long zZCard(String key) {
        return redisTemplate.opsForZSet().zCard(key);
    }

    /**
     * 获取集合中value元素的score值
     * 如果member元素不是有序集key的成员,或key不存在,返回nil。
     *
     * @param key key值
     * @param value value值
     * @return 有序集key中,成员member的score值。
     */
    public Double zScore(String key, Object value) {
        return redisTemplate.opsForZSet().score(key, value);
    }

    /**
     * 移除指定索引位置的成员
     *
     * 返回有序集key中,指定区间内的成员。其中成员的位置按score值递减(从大到小)来排列。具有相同score值的成员按字典序的反序排列
     *
     * @param key key值
     * @param start 开始索引
     * @param end 结束索引
     * @return 返回有序集key中,指定区间内的成员。其中成员的位置按score值递减(从大到小)来排列。具有相同score值的成员按字典序的反序排列
     */
    public Long zRemoveRange(String key, long start, long end) {
        return redisTemplate.opsForZSet().removeRange(key, start, end);
    }

    /**
     * 根据指定的score值的范围来移除成员
     * 移除有序集key中,所有score值介于min和max之间(包括等于min或max)的成员
     *
     * @param key key值
     * @param min 最小值
     * @param max 最大值
     * @return 删除的元素的个数
     */
    public Long zRemoveRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
    }

    /**
     * 获取key和otherKey的并集并存储在destKey中
     *
     * @param key key值
     * @param otherKey 另外的key值
     * @param destKey 存储destKey
     * @return 结果有序集合destKey中元素个数
     */
    public Long zUnionAndStore(String key, String otherKey, String destKey) {
        return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);
    }

    /**
     * 获取key和otherKey的并集并存储在destKey中
     * @param key key值
     * @param otherKeys 另外的key值(集合)多个
     * @param destKey 存储destKey
     * @return  结果有序集合destKey中元素个数
     */
    public Long zUnionAndStore(String key, Collection<String> otherKeys,
                               String destKey) {
        return redisTemplate.opsForZSet().unionAndStore(key, otherKeys, destKey);
    }

    /**
     * 获取key和otherKey的交集并存储在destKey中
     *
     * @param key key值
     * @param otherKey 另外的key值
     * @param destKey 存储destKey
     * @return 结果有序集合destKey中元素个数
     */
    public Long zIntersectAndStore(String key, String otherKey, String destKey) {
        return redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey);
    }

    /**
     * 获取key和otherKey的交集并存储在destKey中
     *
     * @param key key值
     * @param otherKeys 另外的key值(集合)多个
     * @param destKey 存储destKey
     * @return 结果有序集合destKey中元素个数
     */
    public Long zIntersectAndStore(String key, Collection<String> otherKeys, String destKey) {
        return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey);
    }

    /**
     *
     * @param key
     * @param options
     * @return
     */
    public Cursor<TypedTuple<Object>> zScan(String key, ScanOptions options) {
        return redisTemplate.opsForZSet().scan(key, options);
    }
}

项目地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值