SpringBoot集成Redis

Java知识点总结:想看的可以从这里进入

2.18、集成Redis

2.18.1、 依赖和yml配置

Spring Boot 提供了对 Redis 集成的组件包:spring-boot-starter-data-redis,它依赖于 spring-data-redis 和 lettuce。Spring Boot1.0 默认使用的是 Jedis 客户端,2.0 替换成了 Lettuce。

redis的java客户端有三种:

  • Jedis: 采用的直连,使阻塞的I/O,且其方法调用都是同步的,程序流需要等到sockets处理完I/O才能执行,不支持异步。Jedis 客户端实例不是线程安全的,所以需要通过连接池来使用Jedis
  • Redisson:实现了分布式和可扩展的Java数据结构。促使使用者对Redis的关注分离,提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列。对字符串的操作支持很差。
  • Lettuce: 基于Netty框架,实例可以在多个线程中共享,是一个完全非阻塞的redis客户端,不存在线程不安全的情况。支持高级的redis特性,比如哨兵、集群、管道、自动重新连接和Redis数据模型

优先使用Lettuce,如果需要分布式锁,分布式集合等分布式的高级特性,添加Redisson结合 Lettuce 使用。

  1. Jedis的依赖:Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用。

    <!--导入jedis的包-->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.2.3</version>
    </dependency>
    
  2. Lettuce的依赖

    <!--redis的依赖,依赖于lettuce-core和spring-data-redis-->
    <dependency>
     <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--redis默认的连接池lettuce-core需要此依赖-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.11.1</version>
    </dependency>
    
  3. Lettuce + Redisson 的依赖

    <!--Redisson的依赖,此依赖会自动引入spring-boot-starter-data-redis的依赖-->
    <dependency>
    	<groupId>org.redisson</groupId>
    	<artifactId>redisson-spring-boot-starter</artifactId>
    	<version>3.17.7</version>
    </dependency>
    

使用YML文件配置Redis的连接和 Lettuce连接池

#配置redis连接池
spring:
	#配置redis连接池
	redis:
        host:       #ip地址
        port: 6379      #端口
        password: 密码  #默认为空,设置密码时使用
        database: 0     # Redis数据库索引(默认为0)
    	timeout: 100000  # 连接超时时间(毫秒)
        lettuce:        #使用lettuce连接池
            pool:
                max-idle: 5    #连接池中的最大空闲连接
                min-idle: 0		# 连接池中的最小空闲连接
                max-wait: 10000   # 连接池最大阻塞等待时间(使用负值表示没有限制)
                max-active: 20    # 连接池最大连接数(使用负值表示没有限制)
2.18.2、封装的操作类

spring-data-redis是Spring中操作Redis的继承模块, 它提供了 RedisTemplate(是SpringDataRedis中对JedisApi的高度封装) 和 StringRedisTemplate 封装类实现对Redis客户端的封装,便于快速操作redis。

相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用,是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装。

  • StringRedisTemplate继承RedisTemplate。

  • RedisTemplate是一个泛型类,而StringRedisTemplate则不是

  • StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作。

  • StringRedisTemplate使用的是 StringRedisSerializer类,;RedisTemplate使用的是JdkSerializationRedisSerializer类,

    • RedisTemplate 存取数据不是以可读的形式展现的,而是以字节数组显示。取数据时如果key不是字节数据,会导致取的数据为null

      image-20210912160325297
    • StringRedisTemplate 是正常的数据存取

      image-20221104182000727

2.18.3、Redis序列化类

RedisTemplate使用的是JdkSerializationRedisSerializer类,如果直接使用它保存进去的是这样的:

image-20221105152745920

image-20221105152731507

虽然可以正常获取数据,但是不方便我们使用,所以我们要使用自定义的配置类将其更改为 JSON 的序列化。

创建redis的config类,设置RedisTemplate的序列化配置

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);

        //自定义的序列化帮助类,
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        
        //添加了ObjectMapper和取消保存对象是是不一样的
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //过期了 enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper. activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        //设置key的,key为StringRedisSerializer的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        //设置value,value采用json序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}

更改完后再进行储存数据:

image-20221105152852046

在序列化时设置的 jackson2JsonRedisSerializer.setObjectMapper(objectMapper); 在设置后保存对象是这样的:

image-20221105160013534

不设置时是这样的:

image-20221105155942665
2.18.4、操作redis的类

在Java我们不会直接通过RedisTemplate来进行操做,而是通过封装一个 RedisUtil 类来操作redis。

//异常说明
public class MyRedisException extends RuntimeException {
    /**
     * 异常编号
     */
    private final int messageCode;
    /**
     * 对messageCode 异常信息进行补充说明
     */
    private final String detailMessage;

    public MyRedisException(int messageCode, String message) { super(message);
        this.messageCode = messageCode; this.detailMessage = message;
    }

    public int getMessageCode() { 
        return messageCode;
    }

    public String getDetailMessage() { 
        return detailMessage;
    }
}
1、操作key
@Component
public final class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * key相关操作
     */

    /**
     * 判断key是否存在
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除key
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    /**
     * 设置key的过期时间
     * @param key  键
     * @param time 时间(秒)
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //查找匹配的key
    public Set<String> keys(String pattern) {
        if (null == pattern) {
            return null;
        }
        return redisTemplate.keys(pattern);
    }

    //移除 key 的过期时间,key 将持久保持
    public Boolean persist(String key) {
        if (null == key) {
            return false;
        }
        return redisTemplate.persist(key);
    }

    /**
     * 根据key 获取过期时间
     * @param key 键 不能为null
     * @return  key 不存在时,返回 -2 。当 key 存在但没有设置剩余生存时间时,返回 -1 。否则,以秒为单位,返回 key的剩余生存时间
     */
    public Long getExpire(String key) {
        if (null == key) {
            throw new MyRedisException(4001004, "key or TomeUnit 不能为空");
        }
         return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

}
2、操作String
    /**
     * String相关数据类型
     */

    //设置指定 key 的值
    public void set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //设置key 的值 并设置过期时间
    public void set(String key, Object value, long time) {
       try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //设置key 的值 并设置过期时间,key存在 不做操作返回false,key不存在设置值返回true
    public Boolean setifAbsen(String key, Object value, long time, TimeUnit unit) {
        if (null == key || null == value || null == unit) {
            throw new MyRedisException(4001004, "kkey、value、unit都不能为空");
        }
        return redisTemplate.opsForValue().setIfAbsent(key, value, time, unit);
    }

    /**
     * 获取指定Key的Value。如果与该Key关联的Value不是string类型,Redis将抛出异常,
     * 因为GET命令只能用于获取string Value,如果该Key不存在,返回null
     */
    public Object get(String key) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 先获取key值对应的value然后再set 新的value 值。
     */
    public Object getSet(String key, Object value) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForValue().getAndSet(key, value);
    }

    /**
     * 通过批量的key获取批量的value
     */
    public List<Object> mget(Collection<String> keys) {
        if (null == keys) {
            return Collections.emptyList();
        }
        return redisTemplate.opsForValue().multiGet(keys);
    }

    //将指定Key的Value原子性的增加increment。如果该Key不存在,其初始值为0,在incrby之后其值为increment。
    //如果Value的值不能转换为整型值,如Hi,该操作将执行失败并抛出相应异常。操作成功则返回增加后的value值。
    public long incrby(String key, long increment) {
        if (null == key) {
            throw new MyRedisException(4001004, "key不能为空");
        }
        
        if (increment < 0) {
            throw new MyRedisException(4001004,"递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, increment);
    }

    //将指定Key的Value原子性的减少decrement。如果该Key不存在,其初始值为0,
    //decrby之后其值为-decrement。如果Value的值不能转换为整型值,该操作将执行失败并抛出相应的异常。操作成功则返回减少后的value值。
    public Long decrby(String key, long decrement) {
        if (null == key) {
            throw new MyRedisException(4001004, "key不能为空");
        }
        if (increment < 0) {
            throw new MyRedisException(4001004,"递增因子必须大于0");
        }
        return redisTemplate.opsForValue().decrement(key, -decrement);
    }

    //如果该Key已经存在,APPEND命令将参数Value的数据追加到已存在Value的末尾。
    //如果该Key不存在,APPEND命令将会创建一个新的Key/Value。返回追加后Value的字符串长度。
    public Integer append(String key, String value) {
        if (key == null) {
            throw new MyRedisException(4001004, "key不能为空");
        }
        return redisTemplate.opsForValue().append(key, value);
    }

3、操作List
    //*向列表左边添加元素。如果该Key不存在,将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的头部插入。
    //如果该键的Value不是链表类型,该命令将将会抛出相关异常。操作成功则返回插入后链表中元素的数量。
    public Long lpush(String key, Object... strs) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForList().leftPushAll(key, strs);
    }

    //*向列表右边添加元素。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的尾部插入。
    //*如果该键的Value不是链表类型,该命令将将会抛出相关异常。操作成功则返回插入后链表中元素的数量。
    public Long rpush(String key, Object... strs) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForList().rightPushAll(key, strs);
    }

    //*返回并弹出指定Key关联的链表中的第一个元素,即头部元素。如果该Key不存在,
    //返回nil。LPOP命令执行两步操作:第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值
    public Object lpop(String key) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForList().leftPop(key);
    }

    //*返回并弹出指定Key关联的链表中的最后一个元素,即头部元素。如果该Key不存在,返回nil。
    //*RPOP命令执行两步操作:第一步是将列表右边的元素从列表中移除,第二步是返回被移除的元素值。
    public Object rpop(String key) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForList().rightPop(key);
    }

    //该命令的参数start和end都是0-based。即0表示链表头部(leftmost)的第一个元素。
    //*其中start的值也可以为负值,-1将表示链表中的最后一个元素,即尾部元素,-2表示倒数第二个并以此类推。
    //*该命令在获取元素时,start和end位置上的元素也会被取出。如果start的值大于链表中元素的数量,
    //*空链表将会被返回。如果end的值大于元素的数量,该命令则获取从start(包括start)开始,链表中剩余的所有元素。
    //注:Redis的列表起始索引为0。显然,LRANGE numbers 0 -1 可以获取列表中的所有元素。返回指定范围内元素的列表。
    public List<Object> lrange(String key, long start, long end) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForList().range(key, start, end);
    }

    //*让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
    //*下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
    //*你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
    public void ltrim(String key, long start, long end) {
        if (null == key) {
            return;
        }
        redisTemplate.opsForList().trim(key, start, end);
    }

    //*该命令将返回链表中指定位置(index)的元素,index是0-based,表示从头部位置开始第index的元素,
    //*如果index为-1,表示尾部元素。如果与该Key关联的不是链表,该命令将返回相关的错误信息。 如果超出index返回这返回nil。
    public Object lindex(String key, long index) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForList().index(key, index);
    }


    //*返回指定Key关联的链表中元素的数量,如果该Key不存在,则返回0。如果与该Key关联的Value的类型不是链表,则抛出相关的异常。
    public Long llen(String key) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForList().size(key);
    }

4、操作Hash
    /**
     * hash数据类型
     */

    //通过key 和 field 获取指定的 value
    public Object hget(String key, Object field) {
        if (null == key || null == field) {
            return null;
        }
        return redisTemplate.opsForHash().get(key, field);
    }

    //为指定的Key设定Field/Value对,如果Key不存在,该命令将创建新Key以用于存储参数中的Field/Value对
    //*如果参数中的Field在该Key中已经存在,则用新值覆盖其原有值。
    //返回1表示新的Field被设置了新值,0表示Field已经存在,用新值覆盖原有值。
    public void hset(String key, Object field, Object value) {
        if (null == key || null == field) {
            return;
        }
        redisTemplate.opsForHash().put(key, field, value);
    }

    //*判断指定Key中的指定Field是否存在,返回true表示存在,false表示参数中的Field或Key不存在。
    public Boolean hexists(String key, Object field) {
        if (null == key || null == field) {
            return false;
        }
        return redisTemplate.opsForHash().hasKey(key, field);
    }

    //*从指定Key的Hashes Value中删除参数中指定的多个字段,如果不存在的字段将被忽略,
    //返回实际删除的Field数量。如果Key不存在,则将其视为空Hashes,并返回0。
    public Long hdel(String key, Object... fields) {
        if (null == key || null == fields || fields.length == 0) {
            return 0L;
        }
        return redisTemplate.opsForHash().delete(key, fields);
    }

    //*通过key获取所有的field和value
    public Map<Object, Object> hgetall(String key) {
        if (key == null) {
            return null;
        }
        return redisTemplate.opsForHash().entries(key);
    }

    //*逐对依次设置参数中给出的Field/Value对。如果其中某个Field已经存在,则用新值覆盖原有值。
    //*如果Key不存在,则创建新Key,同时设定参数中的Field/Value。
    public void hmset(String key, Map<String, Object> hash) {
        if (null == key || null == hash) {
            return;
        }
        redisTemplate.opsForHash().putAll(key, hash);
    }

    //*获取和参数中指定Fields关联的一组Values,其返回顺序等同于Fields的请求顺序。
    //*如果请求的Field不存在,其值对应的value为null。
    public List<Object> hmget(String key, Collection<Object> fields) {
        if (null == key || null == fields) {
            return null;
        }
        return redisTemplate.opsForHash().multiGet(key, fields);
    }

    //*对应key的字段自增相应的值
    public Long hIncrBy(String key, Object field, long increment) {
        if (null == key || null == field) {
            throw new MyRedisException(4001004, "key or field 不能为空");
        }
        return redisTemplate.opsForHash().increment(key, field, increment);
    }


5、操作set
    /**
     * set数据
     */
    //*如果在插入的过程用,参数中有的成员在Set中已经存在,该成员将被忽略,而其它成员仍将会被正常插入。
    //如果执行该命令之前,该Key并不存在,该命令将会创建一个新的Set,此后再将参数中的成员陆续插入。返回实际插入的成员数量
    public Long sadd(String key, Object... members) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForSet().add(key, members);

    }

    //返回Set中成员的数量,如果该Key并不存在,返回0。
    public Long scard(String key) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForSet().size(key);

    }

    //*判断参数中指定成员是否已经存在于与Key相关联的Set集合中。返回true表示已经存在,false表示不存在,或该Key本身并不存
    //在。
    public Boolean sismember(String key, Object member) {
        if (null == key) {
            return false;
        }
        return redisTemplate.opsForSet().isMember(key, member);

    }

    //随机的返回Set中的一个成员,不同的是该命令并不会删除返回的成员。
    public Object srandmember(String key) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForSet().randomMember(key);
    }

    //*和SPOP一样,随机的返回Set中的一个成员,不同的是该命令并不会删除返回的成员。
    //*还可以传递count参数来一次随机获得多个元素,根据count的正负不同,具体表现也不同。
    //*当count 为正数时,SRANDMEMBER 会随机从集合里获得count个不重复的元素。
    //*如果count的值大于集合中的元素个数,则SRANDMEMBER 会返回集合中的全部元素。
    //*当count为负数时,SRANDMEMBER 会随机从集合里获得|count|个的元素,如果|count|大与集合中的元素,
    //*就会返回全部元素不够的以重复元素补齐,如果key不存在则返回nil。
    public List<Object> srandmember(String key, int count) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForSet().randomMembers(key, count);
    }

    //*通过key随机删除一个set中的value并返回该值
    public Object spop(String key) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForSet().pop(key);
    }

    //*通过key获取set中所有的value
    public Set<Object> smembers(String key) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForSet().members(key);

    }

    //*从与Key关联的Set中删除参数中指定的成员,不存在的参数成员将被忽略,
    //*如果该Key并不存在,将视为空Set处理。返回从Set中实际移除的成员数量,如果没有则返回0。
    public Long srem(String key, Object... members) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForSet().remove(key, members);
    }

    //*将元素value从一个集合移到另一个集合
    public Boolean smove(String srckey, String dstkey, Object member) {
        if (null == srckey || null == dstkey) {
            return false;
        }
        return redisTemplate.opsForSet().move(srckey, member, dstkey);

    }

    // *获取两个集合的并集
    public Set<Object> sUnion(String key, String otherKeys) {
        if (null == key || otherKeys == null) {
            return null;
        }
        return redisTemplate.opsForSet().union(key, otherKeys);
    }

6、操作ZSet
    /**
     * Zset数据
     */
    //添加参数中指定的所有成员及其分数到指定key的Sorted Set中,在该命令中我们可以指定多组score/member作为参数。
    //*如果在添加时参数中的某一成员已经存在,该命令将更新此成员的分数为新值,同时再将该成员基于新值重新排序。
    //如果键不存在,该命令将为该键创建一个新的Sorted Set Value,并将score/member对插入其中。
    public Boolean zadd(String key, double score, Object member) {
        if (null == key) {
            return false;
        }
        return redisTemplate.opsForZSet().add(key, member, score);
    }

    //*该命令将移除参数中指定的成员,其中不存在的成员将被忽略。
    //如果与该Key关联的Value不是Sorted Set,相应的错误信息将被返回。 如果操作成功则返回实际被删除的成员数量。
    public Long zrem(String key, Object... members) {
        if (null == key || null == members) {
            return 0L;
        }
        return redisTemplate.opsForZSet().remove(key, members);
    }

    //*返回Sorted Set中的成员数量,如果该Key不存在,返回0。
    public Long zcard(String key) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForZSet().size(key);
    }

    //*该命令将为指定Key中的指定成员增加指定的分数。如果成员不存在,该命令将添加该成员并假设其初始分数为0,
    //*此后再将其分数加上increment。如果Key不存在,该命令将创建该Key及其关联的Sorted Set,
    //*并包含参数指定的成员,其分数为increment参数。如果与该Key关联的不是Sorted Set类型,
    //*相关的错误信息将被返回。如果不报错则以串形式表示的新分数。
    public Double zincrby(String key, double score, Object member) {
        if (null == key) {
            throw new MyRedisException(4001004, "key 不能为空");
        }
        return redisTemplate.opsForZSet().incrementScore(key, member, score);
    }

    //*该命令用于获取分数(score)在min和max之间的成员数量。
    //*(min=<score<=max)如果加上了“(”着表明是开区间例如zcount key (min max 则 表示(min<score=<max)
    //*同理zcount key min (max 则表明(min=<score<max) 返回指定返回数量。
    public Long zcount(String key, double min, double max) {
        if (null == key) {
            return 0L;
        }
        return redisTemplate.opsForZSet().count(key, min, max);
    }

    //*Sorted Set中的成员都是按照分数从低到高的顺序存储,该命令将返回参数中指定成员的位置值,
    //其中0表示第一个成员,它是Sorted Set中分数最低的成员。 如果该成员存在,则返回它的位置索引值。否则返回nil
    public Long zrank(String key, Object member) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForZSet().rank(key, member);
    }

    //*如果该成员存在,以字符串的形式返回其分数,否则返回null
    public Double zscore(String key, Object member) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForZSet().score(key, member);
    }

    //*该命令返回顺序在参数start和stop指定范围内的成员,这里start和stop参数都是0-based,即0表示第一个成员,-1表示最后    一个成员。如果start大于该Sorted
    //*Set中的最大索引值,或start > stop,此时一个空集合将被返回。如果stop大于最大索引值,
    //*该命令将返回从start到集合的最后一个成员。如果命令中带有可选参数WITHSCORES选项,
    //*该命令在返回的结果中将包含每个成员的分数值,如value1,score1,value2,score2...。
    public Set<Object> zrange(String key, long min, long max) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForZSet().range(key, min, max);
    }

    //*该命令的功能和ZRANGE基本相同,唯一的差别在于该命令是通过反向排序获取指定位置的成员,
    //*即从高到低的顺序。如果成员具有相同的分数,则按降序字典顺序排序。
    public Set<Object> zReverseRange(String key, long start, long end) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForZSet().reverseRange(key, start, end);

    }

    //*该命令将返回分数在min和max之间的所有成员,即满足表达式min <= score <= max的成员,
    //*其中返回的成员是按照其分数从低到高的顺序返回,如果成员具有相同的分数,
    //*则按成员的字典顺序返回。可选参数LIMIT用于限制返回成员的数量范围。
    //*可选参数offset表示从符合条件的第offset个成员开始返回,同时返回count个成员。
    //*可选参数WITHSCORES的含义参照ZRANGE中该选项的说明。*最后需要说明的是参数中min和max的规则可参照命令ZCOUNT。
    public Set<Object> zrangebyscore(String key, double min, double max) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }

    //*该命令除了排序方式是基于从高到低的分数排序之外,其它功能和参数含义均与ZRANGEBYSCORE相同。
    //*需要注意的是该命令中的min和max参数的顺序和ZRANGEBYSCORE命令是相反的。
    public Set<Object> zrevrangeByScore(String key, double min, double max) {
        if (null == key) {
            return null;
        }
        return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

辰 羽

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

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

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

打赏作者

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

抵扣说明:

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

余额充值