06.`spring boot`集成`redis`

1. 依赖
  1. 依赖

    <!-- redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    <!-- redis-pool -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    
  2. 说明

    1. spring boot已经集成,无需声明版本号
    2. commons-pool2redis连接池
2.主配置文件
  1. 哨兵模式

    spring:
      redis:
        lettuce:
          pool:
            max-active: 10
            min-idle: 5
        # 主的密码
        password: passsword
        sentinel:
          # 主的地址,如果是 docker-compose,则为容器名
          master: redis-master
          # sentinel 的地址,也可为容器名的地址
          nodes: sentinel1:26379,sentinel2:26379,sentinel3:26379    
    
  2. 集群模式

    spring:
      redis:
        lettuce:
          pool:
            max-active: 10
            min-idle: 5
        # 集群的密码,密码要一致
        password: passsword
        cluster:
          # 也可以逗号 , 分开
          nodes:
            - 172.29.0.2:6379
            - 172.29.0.3:6379
            - 172.29.0.4:6379
            - 172.29.0.5:6379
            - 172.29.0.6:6379
            - 172.29.0.7:6379
          # 执行命令时的最大重定向次数
          max-redirects: 3    
    
  3. 单机模式

    spring:
      redis:
        host: 120.25.207.44
        port: 6379
        password: password
        database: 1
        lettuce:
          pool:
            min-idle: 5
            max-active: 10    
    
3. RedisConfig配置类
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * 说明:
 *
 * @author sheng
 */
@Slf4j
@Data
@Configuration
public class RedisConfig {
    /**
     * 将 RedisTemplate 对象注册到容器中
     *
     * @param factory RedisConnectionFactory 工厂
     * @return RedisTemplate 对象
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 对 key 进行序列化
        // StringRedisSerializer 当需要存储 String 类型的 key 时序列化使用
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // 对 String 的 key 进行序列化
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // 对 Hash 的 key 进行序列化
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // 也可以使用 FastJsonRedisSerializer、Jackson2JsonRedisSerializer 来序列化
        // 对值进行序列化
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        // 开启事务
        redisTemplate.setEnableTransactionSupport(true);
        // 注入到 factory 工厂中
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
}
4. redis-dmo 源码
5. 工具类
package com.sheng.boot.redis.utils;

import io.lettuce.core.KeyScanCursor;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.ScanArgs;
import io.lettuce.core.ScanCursor;
import io.lettuce.core.api.async.RedisAsyncCommands;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author sheng
 * @date 2023-03-06 10:30
 */
@Slf4j
@Component
public class RedisUtils {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 操作字符串
     */
    private ValueOperations<String, Object> valueOperations;
    /**
     * 操作hash
     */
    private HashOperations<String, String, Object> hashOperations;
    /**
     * 操作List
     */
    private ListOperations<String, Object> listOperations;
    /**
     * 操作 set
     */
    private SetOperations<String, Object> setOperations;
    /**
     * 操作zSet
     */
    private ZSetOperations<String, Object> zSetOperations;

    /**
     * 初始化
     */
    @PostConstruct
    public void initOperations() {
        valueOperations = redisTemplate.opsForValue();
        hashOperations = redisTemplate.opsForHash();
        listOperations = redisTemplate.opsForList();
        setOperations = redisTemplate.opsForSet();
        zSetOperations = redisTemplate.opsForZSet();
    }

    // key 的操作

    /**
     * 删除 key
     *
     * @param key 要删除的 key
     * @return 成功返回 true
     */
    public boolean delete(String key) {
        return Objects.equals(redisTemplate.delete(key), true);
    }

    /**
     * 批量删除 key
     *
     * @param keys 要删除的 key 的 Collection<String>集合
     * @return 删除成功数
     */
    public long delete(Collection<String> keys) {
        Long delete = redisTemplate.delete(keys);
        return Objects.nonNull(delete) ? delete : 0;
    }

    /**
     * 序列化 key 为 byte[] 数组
     *
     * @param key 要序列化的 key
     * @return byte[] 数组
     */
    public byte[] dump(String key) {
        return redisTemplate.dump(key);
    }

    /**
     * key 是否存在
     *
     * @param key key
     * @return 存在则 true,否则 false
     */
    public boolean hasKey(String key) {
        return Objects.equals(redisTemplate.hasKey(key), true);
    }

    /**
     * 设置过期时间
     *
     * @param key      设置过期时间的 key
     * @param timeout  过期时间
     * @param timeUnit TimeUnit 枚举类对象,单位
     * @return 成功返回 true
     */
    public boolean expire(String key, long timeout, TimeUnit timeUnit) {
        return Objects.equals(redisTemplate.expire(key, timeout, timeUnit), true);
    }

    /**
     * 设置过期时间
     *
     * @param key  设置过期时间的 key
     * @param date 过期时间的日期,Date 对象
     * @return 成功返回 true
     */
    public boolean expireAt(String key, Date date) {
        return Objects.equals(redisTemplate.expireAt(key, date), true);
    }

    /**
     * 查找匹配的 key,会阻塞,一般禁止使用
     *
     * @param pattern 匹配规则
     * @return Set<String>
     */
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * 获取指定格式的所有 key
     *
     * @param pattern 匹配规则,如 key*
     * @return 指定格式的所有key
     */
    public Set<String> scanKeys(String pattern) {
        return redisTemplate.execute(connection -> {
            Set<String> redisKeySet = new HashSet<>(16);
            try {
                //游标
                ScanCursor curs = ScanCursor.INITIAL;
                @SuppressWarnings("unchecked")
                RedisAsyncCommands<byte[], Object> nativeConnection = (RedisAsyncCommands<byte[], Object>) connection.getNativeConnection();
                //采用 SCAN 命令,迭代遍历所有key
                while (!curs.isFinished()) {
                    long count = 10000L;
                    log.info("SCAN [{}] MATCH [{}] COUNT [{}]", curs.getCursor(), pattern, count);
                    ScanArgs args = ScanArgs.Builder.matches(pattern).limit(count);
                    RedisFuture<KeyScanCursor<byte[]>> redisFuture = nativeConnection.scan(curs, args);
                    KeyScanCursor<byte[]> keyCurs = redisFuture.get();
                    List<byte[]> keys = keyCurs.getKeys();
                    log.info("return size:{}", keys.size());
                    keys.forEach(key -> redisKeySet.add(new String(key, StandardCharsets.UTF_8)));
                    curs = keyCurs;
                }
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
            return redisKeySet;
        }, true);
    }

    /**
     * 将当前数据库的 key 移动到给定的数据库 db 当中
     *
     * @param key     移动的 key
     * @param dbIndex 目标数据库
     * @return 成功返回 true
     */
    public boolean move(String key, int dbIndex) {
        return Objects.equals(redisTemplate.move(key, dbIndex), true);
    }

    /**
     * 移除 key 的过期时间,key 将持久保持
     *
     * @param key 移除的 key
     * @return 成功返回 true
     */
    public boolean persist(String key) {
        return Objects.equals(redisTemplate.persist(key), true);
    }

    /**
     * 返回 key 的剩余的过期时间
     *
     * @param key      查看的 key
     * @param timeUnit TimeUnit 枚举类,单位
     * @return 返回时间
     */
    public long getExpire(String key, TimeUnit timeUnit) {
        Long expire = redisTemplate.getExpire(key, timeUnit);
        return Objects.nonNull(expire) ? expire : 0;
    }

    /**
     * 返回 key 的剩余的过期时间
     *
     * @param key key
     * @return 剩余过期时间
     */
    public long getExpire(String key) {
        Long expire = redisTemplate.getExpire(key);
        return Objects.nonNull(expire) ? expire : 0;
    }

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

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

    /**
     * 仅当 newKey 不存在时,将 oldKey 改名为 newKey
     *
     * @param oldKey key 原来的名称
     * @param newKey 新的名称
     * @return 成功返回 true
     */
    public boolean renameIfAbsent(String oldKey, String newKey) {
        return Objects.equals(redisTemplate.renameIfAbsent(oldKey, newKey), true);
    }

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

    // string 相关操作

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

    /**
     * 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
     *
     * @param key    key
     * @param value  复写的参数值
     * @param offset 从指定位置开始覆写
     */
    public void set(String key, String value, long offset) {
        valueOperations.set(key, value, offset);
    }

    /**
     * 从偏移量 offset 开始,用 value 参数覆写给定 key 所存储的值
     *
     * @param key     key
     * @param value   值
     * @param timeout 过期时间
     * @param unit    {@link TimeUnit} 过期时间单位
     */
    public void set(String key, Object value, long timeout, TimeUnit unit) {
        valueOperations.set(key, value, timeout, unit);
    }

    /**
     * 只有在 key 不存在时设置 key 的值
     *
     * @param key   key
     * @param value 值
     * @return 之前已经存在返回false, 不存在返回true
     */
    public boolean setIfAbsent(String key, String value) {
        return Objects.equals(valueOperations.setIfAbsent(key, value), true);
    }

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

    /**
     * 返回 key 中字符串值的子字符
     *
     * @param key   key
     * @param start 截取的初始索引
     * @param end   截取的末索引
     * @return 子字符串
     */
    public Object get(String key, long start, long end) {
        return valueOperations.get(key, start, end);
    }

    /**
     * 将给定 key 的值设为 value ,并返回 key 的旧值(old value)
     *
     * @param key   key
     * @param value 要设定的新值
     * @return key 原来的值
     */
    public Object getAndSet(String key, String value) {
        return valueOperations.getAndSet(key, value);
    }

    /**
     * 设置 ASCII 码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第 offset 位值变为value
     *
     * @param key    key
     * @param offset 位置,二进制的位数
     * @param value  值,true为 1,false为 0
     * @return 成功返回 true
     */
    public boolean setBit(String key, long offset, boolean value) {
        return Objects.equals(valueOperations.setBit(key, offset, value), true);
    }

    /**
     * 对 key 所储存的字符串值,获取指定偏移量上的位(bit)
     *
     * @param key    key
     * @param offset 偏移量
     * @return 成功返回 true
     */
    public boolean getBit(String key, long offset) {
        return Objects.equals(valueOperations.getBit(key, offset), true);
    }

    /**
     * 批量获取
     *
     * @param keys key 集合
     * @return key 对应的值的集合
     */
    public List<Object> multiGet(Collection<String> keys) {
        return valueOperations.multiGet(keys);
    }

    /**
     * 获取字符串的长度
     *
     * @param key key
     * @return key对应值的长度
     */
    public long size(String key) {
        Long size = valueOperations.size(key);
        return Objects.nonNull(size) ? size : 0;
    }

    /**
     * 批量添加
     *
     * @param maps 添加的字符串的 map
     */
    public void multiSet(Map<String, ?> maps) {
        valueOperations.multiSet(maps);
    }

    /**
     * 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
     *
     * @param maps 添加的字符串的 map
     * @return 之前已经存在返回 false, 不存在返回 true
     */
    public boolean multiSetIfAbsent(Map<String, ?> maps) {
        return Objects.equals(valueOperations.multiSetIfAbsent(maps), true);
    }

    /**
     * 增加(自增长), 负数则为自减
     *
     * @param key       key
     * @param increment 整型,自增的 值
     * @return 自增后的值
     */
    public long incrBy(String key, long increment) {
        Long last = valueOperations.increment(key, increment);
        return Objects.nonNull(last) ? last : 0;
    }

    /**
     * 增加(自增长), 负数则为自减
     *
     * @param key       key
     * @param increment double,自增的值
     * @return 自增后的值
     */
    public double incrByDouble(String key, double increment) {
        Double last = valueOperations.increment(key, increment);
        return Objects.nonNull(last) ? last : 0D;
    }

    /**
     * 追加到末尾
     *
     * @param key   key
     * @param value 追加的值
     * @return key 的长度
     */
    public int append(String key, String value) {
        Integer len = valueOperations.append(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    // hash相关操作

    /**
     * 获取存储在哈希表中指定字段的值
     *
     * @param key   key
     * @param field hash的键
     * @return 键对应的值
     */
    public Object hGet(String key, String field) {
        return hashOperations.get(key, field);
    }

    /**
     * 获取所有给定 key hash 的值
     *
     * @param key key
     * @return key 对应的所有的键值对 map
     */
    public Map<String, Object> hGetAll(String key) {
        return hashOperations.entries(key);
    }

    /**
     * 获取所有给定字段的值
     *
     * @param key    key
     * @param fields key 对应的键的集合
     * @return 键对应的值的集合
     */
    public List<Object> hMultiGet(String key, List<String> fields) {
        return hashOperations.multiGet(key, fields);
    }

    /**
     * 给名为 key 的 hash 增加 hashKey-value 键值对
     *
     * @param key     key
     * @param hashKey hash对应的键
     * @param value   键对应的值
     */
    public void hPut(String key, String hashKey, Object value) {
        hashOperations.put(key, hashKey, value);
    }

    /**
     * 给名为 key 的 hash 增加 maps 所有的键值对
     *
     * @param key  键
     * @param maps 要增加的 map
     */
    public void hPutAll(String key, Map<String, ?> maps) {
        hashOperations.putAll(key, maps);
    }

    /**
     * 仅当 hashKey不存在时才设置
     *
     * @param key     key hash
     * @param hashKey hash 对应的键
     * @param value   设置的值
     * @return 成功返回 true
     */
    public boolean hPutIfAbsent(String key, String hashKey, Object value) {
        return hashOperations.putIfAbsent(key, hashKey, value);
    }

    /**
     * 删除一个或多个哈希表字段
     *
     * @param key    hash
     * @param fields 删除的键
     * @return 删除的个数
     */
    public long hDelete(String key, Object... fields) {
        return hashOperations.delete(key, fields);
    }

    /**
     * 查看哈希表 key 中,指定的字段是否存在
     *
     * @param key   hash
     * @param field 要判断的键
     * @return 存在返回 true
     */
    public boolean hHasKey(String key, String field) {
        return hashOperations.hasKey(key, field);
    }

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * @param key       hash
     * @param field     hash 对应的键
     * @param increment 自增的值,负数为减
     * @return 增加后的值
     */
    public long hIncrBy(String key, String field, long increment) {
        return hashOperations.increment(key, field, increment);
    }

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * @param key       hash
     * @param field     hash 对应的键
     * @param increment 自增的值,负数为减
     * @return 增加后的值
     */
    public double hIncrByDouble(String key, String field, Double increment) {
        return hashOperations.increment(key, field, increment);
    }

    /**
     * 获取所有哈希表中的字段
     *
     * @param key hash
     * @return hash 所有的键的 Set 集合
     */
    public Set<String> hKeys(String key) {
        return hashOperations.keys(key);
    }

    /**
     * 获取哈希表中字段的数量
     *
     * @param key key
     * @return 键的数量
     */
    public long hSize(String key) {
        return hashOperations.size(key);
    }

    /**
     * 获取哈希表中所有值
     *
     * @param key hash
     * @return hash 所有的值的 List 集合
     */
    public List<Object> hValues(String key) {
        return hashOperations.values(key);
    }

    /**
     * 迭代哈希表中的键值对
     *
     * @param key     hash
     * @param options 迭代的条件
     * @return 连接,如果报错,可以手动关闭,调用 .close()
     */
    public Cursor<Map.Entry<String, Object>> hScan(String key, ScanOptions options) {
        return hashOperations.scan(key, options);
    }

    // list相关操作

    /**
     * 通过索引获取列表中的元素
     *
     * @param key   list 对应的 key
     * @param index 索引
     * @return 对应的值
     */
    public Object lIndex(String key, long index) {
        return listOperations.index(key, index);
    }

    /**
     * 获取列表指定范围内的元素
     *
     * @param key   key
     * @param start 开始位置, 0是开始位置
     * @param end   结束位置, -1返回所有
     * @return 元素的 集合
     */
    public List<Object> lRange(String key, long start, long end) {
        return listOperations.range(key, start, end);
    }

    /**
     * 存储在list头部
     *
     * @param key   key
     * @param value 值
     * @return 集合的长度
     */
    public long lLeftPush(String key, Object value) {
        Long len = listOperations.leftPush(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 将值全部存储在头部
     *
     * @param key   key
     * @param value 值
     * @return 集合的长度
     */
    public long lLeftPushAll(String key, Object... value) {
        Long len = listOperations.leftPushAll(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 将集合里面的值全部存储在头部
     *
     * @param key   key
     * @param value Collection<String>集合
     * @return 集合的长度
     */
    public long lLeftPushAll(String key, Collection<Object> value) {
        Long len = listOperations.leftPushAll(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 当list存在的时候才加入
     *
     * @param key   key
     * @param value 值
     * @return 集合的长度
     */
    public long lLeftPushIfPresent(String key, Object value) {
        Long len = listOperations.leftPushIfPresent(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 如果 pivot存在,再 pivot前面添加
     *
     * @param key   key
     * @param pivot 是否存在的值
     * @param value pivot 存在则在其前面添加的值
     * @return 集合的长度,失败返回 -1
     */
    public long lLeftPush(String key, Object pivot, Object value) {
        Long len = listOperations.leftPush(key, pivot, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * list 尾部添加
     *
     * @param key   key
     * @param value 值
     * @return 集合的长度
     */
    public long lRightPush(String key, Object value) {
        Long len = listOperations.rightPush(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 尾部添加所有
     *
     * @param key   key
     * @param value 添加的值
     * @return 集合的长度
     */
    public long lRightPushAll(String key, Object... value) {
        Long len = listOperations.rightPushAll(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 尾部添加所有
     *
     * @param key   list key
     * @param value 要添加的 Collection<String> 集合
     * @return 集合的长度
     */
    public long lRightPushAll(String key, Collection<Object> value) {
        Long len = listOperations.rightPushAll(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 为已存在的 list 列表添加值
     *
     * @param key   key
     * @param value 要添加的值
     * @return 集合的长度
     */
    public long lRightPushIfPresent(String key, Object value) {
        Long len = listOperations.rightPushIfPresent(key, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 在 pivot 元素的右边添加值
     *
     * @param key   list
     * @param pivot list 存在的元素,在其右边添加
     * @param value 添加的值
     * @return 集合的长度
     */
    public long lRightPush(String key, Object pivot, Object value) {
        Long len = listOperations.rightPush(key, pivot, value);
        return Objects.nonNull(len) ? len : 0;
    }

    /**
     * 通过索引设置列表元素的值
     *
     * @param key   list
     * @param index 位置
     * @param value 添加的值
     */
    public void lSet(String key, long index, String value) {
        listOperations.set(key, index, value);
    }

    /**
     * 移出并获取列表的第一个元素
     *
     * @param key key
     * @return 删除的元素
     */
    public Object lLeftPop(String key) {
        return listOperations.leftPop(key);
    }

    /**
     * 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param key      key
     * @param timeout  等待时间
     * @param timeUnit 时间单位
     * @return 移除的元素
     */
    public Object lLeftPop(String key, long timeout, TimeUnit timeUnit) {
        return listOperations.leftPop(key, timeout, timeUnit);
    }

    /**
     * 移除并获取列表最后一个元素
     *
     * @param key key
     * @return 删除的元素
     */
    public Object lRightPop(String key) {
        return listOperations.rightPop(key);
    }

    /**
     * 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param key      key
     * @param timeout  等待时间
     * @param timeUnit 时间单位
     * @return 移除的元素
     */
    public Object lRightPop(String key, long timeout, TimeUnit timeUnit) {
        return listOperations.rightPop(key, timeout, timeUnit);
    }

    /**
     * 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
     *
     * @param sourceKey      源 list
     * @param destinationKey 目标 list
     * @return 源 list 移除的元素
     */
    public Object lRightPopAndLeftPush(String sourceKey, String destinationKey) {
        return listOperations.rightPopAndLeftPush(sourceKey, destinationKey);
    }

    /**
     * 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param sourceKey      源 list
     * @param destinationKey 目标 list
     * @param timeout        超时时间
     * @param timeUnit       TimeUnit 枚举类对象,单位
     * @return 源 list 移除的元素
     */
    public Object lRightPopAndLeftPush(String sourceKey, String destinationKey, long timeout, TimeUnit timeUnit) {
        return listOperations.rightPopAndLeftPush(sourceKey, destinationKey, timeout, timeUnit);
    }

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

    /**
     * 裁剪list
     *
     * @param key   key
     * @param start 裁剪的起始索引
     * @param end   裁剪的末尾索引
     */
    public void lTrim(String key, long start, long end) {
        listOperations.trim(key, start, end);
    }

    /**
     * 获取列表长度
     *
     * @param key key
     * @return list 长度
     */
    public long lSize(String key) {
        Long size = listOperations.size(key);
        return Objects.nonNull(size) ? size : 0;
    }

    // set相关操作

    /**
     * set添加元素
     *
     * @param key    key
     * @param values 添加的元素
     * @return 成功个数
     */
    public long sAdd(String key, Object... values) {
        Long count = setOperations.add(key, values);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * set移除元素
     *
     * @param key    key
     * @param values 删除的元素
     * @return 删除成功个数
     */
    public long sRemove(String key, Object... values) {
        Long removeCount = setOperations.remove(key, values);
        return Objects.nonNull(removeCount) ? removeCount : 0;
    }

    /**
     * 移除并返回集合的一个随机元素
     *
     * @param key set 集合 key
     * @return 移除的元素
     */
    public Object sPop(String key) {
        return setOperations.pop(key);
    }

    /**
     * 将元素value从一个集合移到另一个集合
     *
     * @param key     源 set
     * @param value   移动的 值
     * @param destKey 目标 set
     * @return 成功返回 true
     */
    public boolean sMove(String key, String value, String destKey) {
        return Objects.equals(setOperations.move(key, value, destKey), true);
    }

    /**
     * 获取集合的大小
     *
     * @param key set 集合
     * @return 集合大小
     */
    public long sSize(String key) {
        Long size = setOperations.size(key);
        return Objects.nonNull(size) ? size : 0;
    }

    /**
     * 判断集合是否包含value
     *
     * @param key   set 集合
     * @param value 是否包含的值
     * @return 存在返回 true
     */
    public boolean sIsMember(String key, Object value) {
        return Objects.equals(setOperations.isMember(key, value), true);
    }

    /**
     * 获取两个集合的交集
     *
     * @param key      集合
     * @param otherKey 集合
     * @return 两个集合的交集
     */
    public Set<Object> sIntersect(String key, String otherKey) {
        return setOperations.intersect(key, otherKey);
    }

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

    /**
     * key集合与otherKey集合的交集存储到destKey集合中
     *
     * @param key      求交集的集合
     * @param otherKey 求交集的集合
     * @param destKey  交集存储的目标集合
     * @return 交集元素个数
     */
    public long sIntersectAndStore(String key, String otherKey, String destKey) {
        Long count = setOperations.intersectAndStore(key, otherKey, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * key集合与多个集合的交集存储到destKey集合中
     *
     * @param key       集合 key
     * @param otherKeys 包含多个集合 key 的集合 Collection<String>
     * @param destKey   交集存储的目标集合
     * @return 添加到 destKey 交集的个数
     */
    public long sIntersectAndStore(String key, Collection<String> otherKeys, String destKey) {
        Long count = setOperations.intersectAndStore(key, otherKeys, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取两个集合的并集
     *
     * @param key       集合
     * @param otherKeys 集合
     * @return 并集
     */
    public Set<Object> sUnion(String key, String otherKeys) {
        return setOperations.union(key, otherKeys);
    }

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

    /**
     * key集合与otherKey集合的并集存储到destKey中
     *
     * @param key      求并集的集合
     * @param otherKey 求并集的集合
     * @param destKey  并集添加到的目标集合
     * @return 添加到目标集合的值的个数
     */
    public long sUnionAndStore(String key, String otherKey, String destKey) {
        Long count = setOperations.unionAndStore(key, otherKey, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * key集合与多个集合的并集存储到destKey中
     *
     * @param key       集合
     * @param otherKeys 包含多个集合 key 的集合 Collection<String>
     * @param destKey   并集添加到的目标集合
     * @return 添加到目标集合的值的个数
     */
    public long sUnionAndStore(String key, Collection<String> otherKeys, String destKey) {
        Long count = setOperations.unionAndStore(key, otherKeys, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取两个集合的差集
     *
     * @param key      集合
     * @param otherKey 集合
     * @return 差集
     */
    public Set<Object> sDifference(String key, String otherKey) {
        return setOperations.difference(key, otherKey);
    }

    /**
     * 获取key集合与多个集合的差集
     *
     * @param key       集合
     * @param otherKeys 包含多个集合 key 的集合 Collection<String>
     * @return 差集
     */
    public Set<Object> sDifference(String key, Collection<String> otherKeys) {
        return setOperations.difference(key, otherKeys);
    }

    /**
     * key集合与otherKey集合的差集存储到destKey中
     *
     * @param key      求差集的集合
     * @param otherKey 求差集的集合
     * @param destKey  差集添加到的目标集合
     * @return 添加到目标集合的值的个数
     */
    public long sDifference(String key, String otherKey, String destKey) {
        Long count = setOperations.differenceAndStore(key, otherKey, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * key集合与多个集合的差集存储到destKey中
     *
     * @param key       求差集的集合
     * @param otherKeys 包含多个集合 key 的集合 Collection<String>
     * @param destKey   差集添加到的目标集合
     * @return 添加到目标集合的值的个数
     */
    public long sDifference(String key, Collection<String> otherKeys, String destKey) {
        Long count = setOperations.differenceAndStore(key, otherKeys, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取集合所有元素
     *
     * @param key 集合
     * @return 集合的所有元素
     */
    public Set<Object> sMembers(String key) {
        return setOperations.members(key);
    }

    /**
     * 随机获取集合中的一个元素
     *
     * @param key 集合
     * @return 随机返回的元素
     */
    public Object sRandomMember(String key) {
        return setOperations.randomMember(key);
    }

    /**
     * 随机获取集合中count个元素,可能获取同一个元素多次
     *
     * @param key   集合
     * @param count 获取的个数
     * @return 获取到的元素的集合
     */
    public List<Object> sRandomMembers(String key, long count) {
        return setOperations.randomMembers(key, count);
    }

    /**
     * 随机获取集合中count个元素并且去除重复的
     *
     * @param key   集合
     * @param count 随机获取的元素个数
     * @return 元素的集合
     */
    public Set<Object> sDistinctRandomMembers(String key, long count) {
        return setOperations.distinctRandomMembers(key, count);
    }

    /**
     * 迭代 set 集合
     *
     * @param key     要迭代的集合
     * @param options 迭代的条件
     * @return 连接,如果报错,可以手动关闭,调用 .close()
     */
    public Cursor<Object> sScan(String key, ScanOptions options) {
        return setOperations.scan(key, options);
    }

    // zSet相关操作

    /**
     * 添加元素,有序集合是按照元素的score值由小到大排列
     *
     * @param key   集合
     * @param value 添加的元素
     * @param score 元素对应的分数
     * @return 成功返回 true
     */
    public boolean zAdd(String key, Object value, double score) {
        return Objects.equals(zSetOperations.add(key, value, score), true);
    }

    /**
     * 将 values 集合的元素添加的 key 集合
     *
     * @param key    集合 key
     * @param values Set<ZSetOperations.TypedTuple<Object>> 集合
     * @return 添加的个数
     */
    public long zAdd(String key, Set<ZSetOperations.TypedTuple<Object>> values) {
        Long count = zSetOperations.add(key, values);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 删除元素
     *
     * @param key    集合
     * @param values 要删除的元素,可变参数
     * @return 删除的个数
     */
    public long zRemove(String key, Object... values) {
        Long removeCount = zSetOperations.remove(key, values);
        return Objects.nonNull(removeCount) ? removeCount : 0;
    }

    /**
     * 增加元素的score值,并返回增加后的值
     *
     * @param key   集合
     * @param value 要添加 score 值的元素
     * @param delta 添加的 score 的值
     * @return 增加后的值
     */
    public double zIncrementScore(String key, Object value, double delta) {
        Double incrementScore = zSetOperations.incrementScore(key, value, delta);
        return Objects.nonNull(incrementScore) ? incrementScore : 0D;
    }

    /**
     * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
     *
     * @param key   集合
     * @param value 要返回排名的值
     * @return 0表示第一位
     */
    public long zRank(String key, Object value) {
        Long rank = zSetOperations.rank(key, value);
        return Objects.nonNull(rank) ? rank : 0;
    }

    /**
     * 返回元素在集合的排名,按元素的score值由大到小排列
     *
     * @param key   集合
     * @param value 要返回排名的值
     * @return 0表示第一位
     */
    public long zReverseRank(String key, Object value) {
        Long reverseRank = zSetOperations.reverseRank(key, value);
        return Objects.nonNull(reverseRank) ? reverseRank : 0;
    }

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

    /**
     * 获取集合元素, 并且把score值也获取
     *
     * @param key   集合
     * @param start 开始位置
     * @param end   结束位置, -1查询所有
     * @return 元素的集合
     */
    public Set<ZSetOperations.TypedTuple<Object>> zRangeWithScores(String key, long start, long end) {
        return zSetOperations.rangeWithScores(key, start, end);
    }

    /**
     * 根据Score值查询集合元素
     *
     * @param key 集合
     * @param min 最小值
     * @param max 最大值
     * @return 元素的集合
     */
    public Set<Object> zRangeByScore(String key, double min, double max) {
        return zSetOperations.rangeByScore(key, min, max);
    }

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

    /**
     * 获取key集合中索引在 [start, end] 的分数在 [min, max] 范围内的所有元素及其分数
     *
     * @param key   集合
     * @param min   score 最小值
     * @param max   score 最大值
     * @param start 开始位置
     * @param end   结束位置, -1查询所有
     * @return 获取到的元素集合
     */
    public Set<ZSetOperations.TypedTuple<Object>> zRangeByScoreWithScores(String key, double min, double max, long start, long end) {
        return zSetOperations.rangeByScoreWithScores(key, min, max, start, end);
    }

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

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

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

    /**
     * 根据Score值查询集合元素及其分数, 从大到小排序
     *
     * @param key 集合
     * @param min score 最小值
     * @param max score 最大值
     * @return 元素集合
     */
    public Set<ZSetOperations.TypedTuple<Object>> zReverseRangeByScoreWithScores(String key, double min, double max) {
        return zSetOperations.reverseRangeByScoreWithScores(key, min, max);
    }

    /**
     * 获取key集合中索引在 [start, end] 的分数在 [min, max] 范围内的所有元素
     *
     * @param key   key 集合
     * @param min   score 最小值
     * @param max   score 最大值
     * @param start 起始位置
     * @param end   末尾位置
     * @return 元素集合
     */
    public Set<Object> zReverseRangeByScore(String key, double min, double max, long start, long end) {
        return zSetOperations.reverseRangeByScore(key, min, max, start, end);
    }

    /**
     * 根据score值获取集合元素个数
     *
     * @param key 集合
     * @param min score 最小值
     * @param max score 最大值
     * @return 元素个数
     */
    public long zCount(String key, double min, double max) {
        Long count = zSetOperations.count(key, min, max);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取集合大小
     *
     * @param key 集合
     * @return 包含的元素的个数
     */
    public long zSize(String key) {
        Long size = zSetOperations.size(key);
        return Objects.nonNull(size) ? size : 0;
    }

    /**
     * 获取集合大小
     *
     * @param key 集合
     * @return 集合大小
     */
    public long zCard(String key) {
        // 不存在返回0
        Long size = zSetOperations.zCard(key);
        return Objects.nonNull(size) ? size : 0;
    }

    /**
     * 获取集合中value元素的score值
     *
     * @param key   集合
     * @param value 要获取 score 值的元素
     * @return score 值,不存在则返回 null
     */
    public Double zScore(String key, Object value) {
        return zSetOperations.score(key, value);
    }

    /**
     * 移除指定索引位置的成员
     *
     * @param key   集合
     * @param start 起始位置
     * @param end   结束位置
     * @return 移除的个数
     */
    public long zRemoveRange(String key, long start, long end) {
        Long count = zSetOperations.removeRange(key, start, end);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 根据指定的score值的范围来移除成员
     *
     * @param key 集合
     * @param min score 最小值
     * @param max score 最大值
     * @return 移除的个数
     */
    public long zRemoveRangeByScore(String key, double min, double max) {
        Long count = zSetOperations.removeRangeByScore(key, min, max);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取 key和 otherKey的并集并存储在destKey中
     *
     * @param key      求并集的集合
     * @param otherKey 求并集的集合
     * @param destKey  并集存储的目标集合
     * @return 添加到目标集合的个数
     */
    public long zUnionAndStore(String key, String otherKey, String destKey) {
        Long count = zSetOperations.unionAndStore(key, otherKey, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取 key和 otherKey 的并集并存储在destKey中
     *
     * @param key       集合 key
     * @param otherKeys 多个集合 key 的 Collection<String> 集合
     * @param destKey   并集添加到的目标集合
     * @return 添加到目标集合的元素个数
     */
    public long zUnionAndStore(String key, Collection<String> otherKeys, String destKey) {
        Long count = zSetOperations.unionAndStore(key, otherKeys, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取 key和 otherKey 的交集并存储在destKey中
     *
     * @param key      集合
     * @param otherKey 集合
     * @param destKey  交集添加到的目标集合
     * @return 添加到目标集合的元素个数
     */
    public long zIntersectAndStore(String key, String otherKey, String destKey) {
        Long count = zSetOperations.intersectAndStore(key, otherKey, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 获取 key和 otherKey 的交集并存储在destKey中
     *
     * @param key       求交集的集合
     * @param otherKeys 求交集的集合
     * @param destKey   交集添加到的目标集合
     * @return 添加到目标集合的元素个数
     */
    public long zIntersectAndStore(String key, Collection<String> otherKeys, String destKey) {
        Long count = zSetOperations.intersectAndStore(key, otherKeys, destKey);
        return Objects.nonNull(count) ? count : 0;
    }

    /**
     * 迭代集合
     *
     * @param key     要迭代的集合
     * @param options 迭代的条件
     * @return 连接,如果报错,调用 .close() 方法关闭
     */
    public Cursor<ZSetOperations.TypedTuple<Object>> zScan(String key, ScanOptions options) {
        return zSetOperations.scan(key, options);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值