Redis封装类

来源:damai_大麦: 🔥 🔥 官方推荐 🔥 🔥 高并发大麦网售票系统,使用 SpringCloud、Kafka、Redis、Sentinel、ElasticSearch、ShardingSphere 等,通过优化锁的策略、多级缓存管理、数据提前预热、精确的定制限流等多种策略,显著的降低下单延迟。此外还解决各种高并发难题的实际落地解决方案。是面试、就业、提高技术的不二选择!https://gitee.com/java-up-up/damai

前言:

该封装针对 Springboot 的 StringRedisTemplate 做了再次封装,使用了json格式存放。

对键值对的操作、String、Hash、Set、ZSet、List提供了封装支持。

在使用过程中,存放直接存放对象类型即可,拿取只需指定class类型。

对key进行了统一的管理约定,用户不能随意在代码中指定key值。

在使用中以接口的形式对外提供api操作,目前实现只有redis一种。

依赖:

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version> <!-- 或最新稳定版 -->
</dependency>

提供的api中,key的类型为RedisKeyBuild,需要使用提供的方法来转换:

【这里将key存放在 RedisKeyManage 枚举中】

java 复制代码
public enum RedisKeyManage {
    Key("key","键值测试","value为TestCacheDto类型","k"),
    Key2("key:%s","键值占位测试","value为TestCacheDto类型","k"),
}

使用 RedisKeyBuild.createRedisKey 方法传入 RedisKeyManage 类型来构建出 RedisKeyBuild ,此方法支持 String.format占用符的使用:

java 复制代码
public final class RedisKeyBuild {
    /**
     * 实际使用的key
     * */
    private final String relKey;

    private RedisKeyBuild(String relKey) {
        this.relKey = relKey;
    }

    /**
     * 构建真实的key
     * @param redisKeyManage key的枚举
     * @param args 占位符的值
     * */
    public static RedisKeyBuild createRedisKey(RedisKeyManage redisKeyManage, Object... args){
        String redisRelKey = String.format(redisKeyManage.getKey(),args);
        return new RedisKeyBuild(SpringUtil.getPrefixDistinctionName() + "-" + redisRelKey);
    }

    public String getRelKey() {
        return relKey;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        RedisKeyBuild that = (RedisKeyBuild) o;
        return relKey.equals(that.relKey);
    }

    @Override
    public int hashCode() {
        return Objects.hash(relKey);
    }
}
  • 封装的api中传入的key的类型为RedisKeyBuildRedisKeyBuild 的构造方法进行了私有化,用户就不用自己进行构建RedisKeyBuild
  • RedisKeyBuild 提供了公共的静态方法createRedisKey ,参数为redisKeyManage,和具体的值
  • 通过这种约束,用户只能调用RedisKeyBuild.createRedisKey,实现了对redis键的统一管理
java 复制代码
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;

import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/*
 * redis方法抽象
 */
public interface RedisCache {

    /**
     * 获取字符串对象
     *
     * @param redisKeyBuild   RedisKeyBuild
     * @param clazz 类对象
     * @param <T>   T
     * @return T 普通对象
     */
    <T> T get(RedisKeyBuild redisKeyBuild, Class<T> clazz);
    
    /**
     * 获取字符串对象(如果缓存中不存在,则执行给定的supplier接口)
     *
     * @param redisKeyBuild   RedisKeyBuild
     * @param clazz 类对象
     * @param <T>   T
     * @param supplier 缓存为空时,执行的逻辑
     * @param ttl      过期时间
     * @param timeUnit 时间单位
     * @return T 普通对象
     */
    <T> T get(RedisKeyBuild redisKeyBuild, Class<T> clazz, Supplier<T> supplier, long ttl, TimeUnit timeUnit);

    /**
     * 返回 key 中字符串值的子字符
     * @param redisKeyBuild 缓存key
     * @param start 开始
     * @param end 结束
     * @return 结果
     */
    String getRange(RedisKeyBuild redisKeyBuild, long start, long end);

    /**
     * 获取字符串对象, 并且字符串中是集合内容
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @param <T> 指定泛型
     * @return List<T>
     */
    <T> List<T> getValueIsList(RedisKeyBuild redisKeyBuild, Class<T> clazz);
    
    /**
     * 获取字符串对象, 并且字符串中是集合内容(如果缓存中不存在,则执行给定的supplier接口)
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @param <T> 指定泛型
     * @param supplier 缓存为空时,执行的逻辑
     * @param ttl      过期时间
     * @param timeUnit 时间单位
     * @return List<T>
     */
    <T> List<T> getValueIsList(RedisKeyBuild redisKeyBuild, Class<T> clazz, Supplier<List<T>> supplier, long ttl, TimeUnit timeUnit);


    /**
     * 通过多个key批量获取多个value
     *
     * @param keyList key集合
     * @return List<String>
     */
    List<String> getKeys(List<RedisKeyBuild> keyList);

    /**
     * 判断key是否存在
     *
     * @param redisKeyBuild redisKeyBuild
     * @return 是否存在 可能为空
     */
    Boolean hasKey(RedisKeyBuild redisKeyBuild);

    /**
     * 删除key
     *
     * @param redisKeyBuild 缓存key
     * @return
     */
    void del(RedisKeyBuild redisKeyBuild);


    /**
     * 批量删除key
     *
     * @param keys key集合
     */
    void del(Collection<RedisKeyBuild> keys);

    /**
     * 设置key过期时间
     *
     * @param redisKeyBuild      RedisKeyBuild
     * @param ttl      过期时间
     * @param timeUnit 时间单位
     * @return 是否成功
     */
    Boolean expire(RedisKeyBuild redisKeyBuild, long ttl, TimeUnit timeUnit);

    /**
     * 获取key超时时间
     *
     * @param redisKeyBuild redisKeyBuild
     * @return 超时时间
     */
    Long getExpire(RedisKeyBuild redisKeyBuild);
    
    /**
     * 获取key超时时间
     *
     * @param redisKeyBuild redisKeyBuild
     * @param timeUnit 时间单位
     * @return 超时时间
     */
    Long getExpire(RedisKeyBuild redisKeyBuild,TimeUnit timeUnit);

    /**
     * 查找匹配的key
     *
     * @param pattern 缓存key
     * @return keys
     */
    Set<String> keys(String pattern);

    /**
     * 将当前数据库的 key 移动到给定的数据库 db 当中
     *
     * @param redisKeyBuild 缓存key
     * @param dbIndex
     * @return
     */
    Boolean move(RedisKeyBuild redisKeyBuild, int dbIndex);

    /**
     * 移除 key 的过期时间,key 将持久保持
     *
     * @param redisKeyBuild 缓存key
     * @return
     */
    Boolean persist(RedisKeyBuild redisKeyBuild);

    /**
     * 从当前数据库中随机返回一个 key
     *
     * @return
     */
    String randomKey();

    /**
     * 修改 key 的名称
     *
     * @param oldKey 缓存key
     * @param newKey 缓存key
     */
    void rename(RedisKeyBuild oldKey, RedisKeyBuild newKey);

    /**
     * 仅当 newKey 不存在时,将 oldKey 改名为 newKey
     *
     * @param oldKey 缓存key
     * @param newKey 缓存key
     * @return
     */
    Boolean renameIfAbsent(RedisKeyBuild oldKey, RedisKeyBuild newKey);

    /**
     * 返回 key 所储存的值的类型
     *
     * @param redisKeyBuild 缓存key
     * @return
     */
    DataType type(RedisKeyBuild redisKeyBuild);

    /**
     * 设置缓存
     *
     * @param redisKeyBuild        缓存key
     * @param object     缓存对象
     */
    void set(RedisKeyBuild redisKeyBuild, Object object);

    /**
     * 设置缓存
     *
     * @param redisKeyBuild        缓存key
     * @param object     缓存对象
     * @param ttl 过期时间
     */
    void set(RedisKeyBuild redisKeyBuild, Object object, long ttl);

    /**
     * 设置缓存
     *
     * @param redisKeyBuild      缓存key
     * @param object   缓存对象
     * @param ttl      过期时间
     * @param timeUnit 时间单位
     */
    void set(RedisKeyBuild redisKeyBuild, Object object, long ttl, TimeUnit timeUnit);

    /**
     * 只有在 key 不存在时设置 key 的值
     *
     * @param redisKeyBuild  缓存key
     * @param object 对象
     * @return 之前已经存在返回false,不存在返回true
     */
    boolean setIfAbsent(RedisKeyBuild redisKeyBuild, Object object);

    /**
     * 获取字符串的长度
     *
     * @param redisKeyBuild 缓存key
     * @return 长度
     */
    Long size(RedisKeyBuild redisKeyBuild);

    /**
     * 批量添加
     *
     * @param map 对象
     */
    void multiSet(Map<RedisKeyBuild, ?> map);

    /**
     * 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
     *
     * @param map 对象
     * @return 之前已经存在返回false,不存在返回true
     */
    boolean multiSetIfAbsent(Map<RedisKeyBuild, ?> map);

    /**
     * 增加(自增长), 负数则为自减
     *
     * @param redisKeyBuild 缓存key
     * @param increment 步长
     * @return
     */
    Long incrBy(RedisKeyBuild redisKeyBuild, long increment);

    /**
     * double类型增加(自增长), 负数则为自减
     * @param redisKeyBuild 缓存key
     * @param increment 步长
     * @return
     */
    Double incrByDouble(RedisKeyBuild redisKeyBuild, double increment);

    /**
     * 追加到末尾
     *
     * @param redisKeyBuild 缓存key
     * @param value 值
     * @return
     */
    Integer append(RedisKeyBuild redisKeyBuild, String value);

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

    /**
     * 放置一个键值对
     *
     * @param redisKeyBuild     hash键
     * @param hashKey hash key
     * @param value   hash value
     */
    void putHash(RedisKeyBuild redisKeyBuild, String hashKey, Object value);

    /**
     * 放置一个键值对 并设置过期时间
     *
     * @param redisKeyBuild           hash键
     * @param hashKey       hash key
     * @param value         hash value
     * @param ttl    过期时间
     */
    void putHash(RedisKeyBuild redisKeyBuild, String hashKey, Object value, long ttl);

    /**
     * 放置一个键值对 并设置过期时间
     *
     * @param redisKeyBuild       hash键
     * @param hashKey   hash key
     * @param value     hash value
     * @param ttl       过期时间
     * @param timeUnit  时间单位
     */
    void putHash(RedisKeyBuild redisKeyBuild, String hashKey, Object value, long ttl, TimeUnit timeUnit);

    /**
     * 放入map中所有键值对
     *
     * @param redisKeyBuild key
     * @param map hash
     */
    void putHash(RedisKeyBuild redisKeyBuild, Map<String, ?> map);

    /**
     * 放入map中所有键值对 并设置过期时间
     *
     * @param redisKeyBuild key
     * @param map hash
     * @param ttl 过期时间
     */
    void putHash(RedisKeyBuild redisKeyBuild, Map<String, ?> map, long ttl);

    /**
     * 放入 Map 中所有键值对 并设置过期时间和时间单位
     *
     * @param redisKeyBuild key
     * @param map hash
     * @param ttl 过期时间
     * @param timeUnit 时间单位
     */
    void putHash(RedisKeyBuild redisKeyBuild, Map<String, ?> map, long ttl, TimeUnit timeUnit);

    /**
     * 仅当hashKey不存在时才设置
     *
     * @param redisKeyBuild 缓存key
     * @param hashKey hash中key
     * @param value 对象
     * @return
     */
    Boolean putHashIfAbsent(RedisKeyBuild redisKeyBuild, String hashKey, Object value);

    /**
     * 从 Hash 中获取普通对象
     *
     * @param redisKeyBuild     key
     * @param hashKey hash key
     * @param clazz   类对象
     * @param <T>     T
     * @return 普通对象
     */
    @SuppressWarnings("all")
    <T> T getForHash(RedisKeyBuild redisKeyBuild, String hashKey, Class<T> clazz);

    /**
     * Hash的value是字符串集合,进行提取
     *
     * @param redisKeyBuild     key
     * @param hashKey hash key
     * @param clazz   类对象
     * @param <T>     T
     * @return 普通对象
     */
    <T> List<T> getValueIsListForHash(RedisKeyBuild redisKeyBuild, String hashKey, Class<T> clazz);

    /**
     * 从 {@code key} 处获取给定 {@code hashKeys} 的值
     *
     * @param redisKeyBuild      key
     * @param hashKeys hashKeys
     * @param clazz    类对象
     * @param <T>      T
     * @return
     */
    <T> List<T> multiGetForHash(RedisKeyBuild redisKeyBuild, List<String> hashKeys, Class<T> clazz);

    /**
     * 谨慎使用!
     * 获取 Hash Key 下所有值
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @param <T> 泛型
     * @return
     */
    <T> List<T> getAllForHash(RedisKeyBuild redisKeyBuild, Class<T> clazz);
    
    /**
     * 谨慎使用!
     * 获取 Hash Key 下所有值,返回值为map
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @param <T> 泛型
     * @return
     */
    <T> Map<String,T> getAllMapForHash(RedisKeyBuild redisKeyBuild, Class<T> clazz);
    /**
     * 判断hash中 key是否存在
     *
     * @param redisKeyBuild 缓存key
     * @param hashKey hash中key
     * @return 结果
     */
    Boolean hasKeyForHash(RedisKeyBuild redisKeyBuild, String hashKey);

    /**
     * 删除hash key
     *
     * @param redisKeyBuild 缓存key
     * @param hashKey hash中key
     * @return 结果
     */
    Long delForHash(RedisKeyBuild redisKeyBuild, String hashKey);

    /**
     * 批量删除hash key
     *
     * @param redisKeyBuild 缓存key
     * @param hashKeys hash中key
     * @return 结果
     */
    Long delForHash(RedisKeyBuild redisKeyBuild, Collection<String> hashKeys);

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment
     *
     * @param redisKeyBuild 缓存key
     * @param hashKey hash中key
     * @param increment 步长
     * @return 结果
     */
    Long incrByForHash(RedisKeyBuild redisKeyBuild, String hashKey, long increment);

    /**
     * 为哈希表 key 中的指定字段的整数值加上增量 increment(double类型)
     *
     * @param redisKeyBuild 缓存key
     * @param hashKey hash中key
     * @param delta 步长
     * @return 结果
     */
    Double incrByDoubleForHash(RedisKeyBuild redisKeyBuild, String hashKey, double delta);

    /**
     * 获取所有哈希表中的hashKey
     *
     * @param redisKeyBuild 缓存key
     * @return 结果
     */
    Set<String> hashKeysForHash(RedisKeyBuild redisKeyBuild);

    /**
     * 获取哈希表中字段的数量
     *
     * @param redisKeyBuild 缓存key
     * @return 结果
     */
    Long sizeForHash(RedisKeyBuild redisKeyBuild);

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

    /**
     * 通过索引获取列表中的元素
     *
     * @param redisKeyBuild 缓存key
     * @param index 索引
     * @param clazz 类型
     * @return 结果
     */
    <T> T indexForList(RedisKeyBuild redisKeyBuild, long index, Class<T> clazz);

    /**
     * List 从左边放入元素
     *
     * @param redisKeyBuild   key
     * @param value value
     * @return 改动行数
     */
    Long leftPushForList(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * List 从左边放入元素
     *
     * @param redisKeyBuild   key
     * @param valueList valueList
     * @return 改动行数
     */
    Long leftPushAllForList(RedisKeyBuild redisKeyBuild, List<?> valueList);

    /**
     * List 从左边放入元素(当list存在的时候才加入)
     *
     * @param redisKeyBuild
     * @param value
     * @return
     */
    Long leftPushIfPresentForList(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * 如果pivot存在,在pivot左边添加
     *
     * @param redisKeyBuild 缓存key
     * @param pivot pivot
     * @param value 对象
     * @return 结果
     */
    Long leftPushForList(RedisKeyBuild redisKeyBuild, Object pivot, Object value);

    /**
     * List 从右边放入元素
     *
     * @param redisKeyBuild   key
     * @param value value
     * @return 改动行数
     */
    Long rightPushForList(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * List 从右边放入元素
     *
     * @param redisKeyBuild   key
     * @param valueList valueList
     * @return 改动行数
     */
    Long rightPushAllForList(RedisKeyBuild redisKeyBuild, List<Object> valueList);

    /**
     * List 从右边放入元素(当list存在的时候才加入)
     *
     * @param redisKeyBuild 缓存key
     * @param value 对象
     * @return 结果
     */
    Long rightPushIfPresentForList(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * 如果pivot存在,在pivot右边添加
     *
     * @param redisKeyBuild 缓存key
     * @param pivot pivot
     * @param value 对象
     * @return 结果
     */
    Long rightPushForList(RedisKeyBuild redisKeyBuild, Object pivot, Object value);

    /**
     * 通过索引设置列表元素的值
     *
     * @param redisKeyBuild 缓存key
     * @param index
     *            位置
     * @param value 对象
     */
    void setForList(RedisKeyBuild redisKeyBuild, long index, Object value);

    /**
     * 移出并获取列表的第一个元素
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @return 删除的元素
     */
    <T> T leftPopForList(RedisKeyBuild redisKeyBuild, Class<T> clazz);

    /**
     * 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @param timeout
     *            等待时间
     * @param unit
     *            时间单位
     * @return
     */
    <T> T leftPopBlockForList(RedisKeyBuild redisKeyBuild, Class<T> clazz, long timeout, TimeUnit unit);

    /**
     * 移除并获取列表最后一个元素
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @return 删除的元素
     */
    <T> T rightPopForList(RedisKeyBuild redisKeyBuild, Class<T> clazz);

    /**
     * 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param redisKeyBuild 缓存key
     * @param clazz 类型
     * @param timeout
     *            等待时间
     * @param unit
     *            时间单位
     * @return
     */
    <T> T rightPopBlockForList(RedisKeyBuild redisKeyBuild, Class<T> clazz, long timeout, TimeUnit unit);

    /**
     * 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
     *
     * @param sourceKey
     * @param destinationKey
     * @param clazz
     * @return
     */
    <T> T rightPopAndLeftPushForList(RedisKeyBuild sourceKey, RedisKeyBuild destinationKey, Class<T> clazz);

    /**
     * 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
     *
     * @param sourceKey 缓存key
     * @param destinationKey 弹出key
     * @param clazz 类型
     * @param timeout 时间
     * @param unit 时间单位
     * @return 结果
     */
    <T> T rightPopBlockAndLeftPushForList(RedisKeyBuild sourceKey, RedisKeyBuild destinationKey, Class<T> clazz, long timeout, TimeUnit unit);

    /**
     * 获取 List 全部数据
     *
     * @param redisKeyBuild 缓存key
     * @param <T> 泛型
     * @param clazz 类型
     * @return
     */
    <T> List<T> getAllForList(RedisKeyBuild redisKeyBuild, Class<T> clazz);

    /**
     * 获取列表指定范围内的元素
     *
     * @param redisKeyBuild 缓存key
     * @param start 开始位置, 0是开始位置
     * @param end 结束位置, -1返回所有
     * @param clazz 类型
     * @return 结果
     */
    <T> List<T> rangeForList(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz);


    /**
     * 删除集合中值等于value得元素
     *
     * @param redisKeyBuild 缓存key
     * @param index
     *            index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素;
     *            index<0, 从尾部开始删除第一个值等于value的元素;
     * @param value 对象
     * @return 结果
     */
    Long removeForList(RedisKeyBuild redisKeyBuild, long index, Object value);


    /**
     * 裁剪list
     *
     * @param redisKeyBuild
     * @param start
     * @param end
     */
    void trimForList(RedisKeyBuild redisKeyBuild, long start, long end);

    /**
     * 获取列表长度
     *
     * @param redisKeyBuild
     * @return
     */
    Long lenForList(RedisKeyBuild redisKeyBuild);


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

    /**
     * set添加元素
     *
     * @param redisKeyBuild
     * @param value
     * @return
     */
    Long addForSet(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * set批量添加元素
     *
     * @param redisKeyBuild
     * @param values
     * @return
     */
    Long addForSet(RedisKeyBuild redisKeyBuild, List<?> values);

    /**
     * set移除元素
     *
     * @param redisKeyBuild
     * @param value
     * @return
     */
    Long removeForSet(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * set批量移除元素
     *
     * @param redisKeyBuild
     * @param values
     * @return
     */
    Long removeForSet(RedisKeyBuild redisKeyBuild, List<?> values);

    /**
     * 移除并返回集合的一个随机元素
     *
     * @param redisKeyBuild
     * @param clazz
     * @return
     */
    <T> T popForSet(RedisKeyBuild redisKeyBuild, Class<T> clazz);

    /**
     * 将元素value从一个集合移到另一个集合
     *
     * @param redisKeyBuild
     * @param value
     * @param destRedisKeyBuild
     * @return
     */
    boolean moveForSet(RedisKeyBuild redisKeyBuild, Object value, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取集合的大小
     *
     * @param redisKeyBuild
     * @return
     */
    Long sizeForSet(RedisKeyBuild redisKeyBuild);

    /**
     * 判断集合是否包含value
     *
     * @param redisKeyBuild
     * @param value
     * @return
     */
    Boolean isMemberForSet(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * 获取两个集合的交集
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param clazz
     * @return
     */
    <T> Set<T> intersectForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, Class<T> clazz);

    /**
     * 获取key集合与多个集合的交集
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param clazz
     * @return
     */
    <T> Set<T> intersectForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, Class<T> clazz);

    /**
     * key集合与otherKey集合的交集存储到destKey集合中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param destRedisKeyBuild
     * @return
     */
    Long intersectAndStoreForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild);

    /**
     * key集合与多个集合的交集存储到destKey集合中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param destRedisKeyBuild
     * @return
     */
    Long intersectAndStoreForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取两个集合的并集
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param clazz
     * @return
     */
    <T> Set<T> unionForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, Class<T> clazz);

    /**
     * 获取key集合与多个集合的并集
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param clazz
     * @return
     */
    <T> Set<T> unionForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, Class<T> clazz);

    /**
     * key集合与otherKey集合的并集存储到destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param destRedisKeyBuild
     * @return
     */
    Long unionAndStoreForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild);

    /**
     * key集合与多个集合的并集存储到destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param destRedisKeyBuild
     * @return
     */
    Long unionAndStoreForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取两个集合的差集
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param clazz
     * @return
     */
    <T> Set<T> differenceForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, Class<T> clazz);

    /**
     * 获取key集合与多个集合的差集
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param clazz
     * @return
     */
    <T> Set<T> differenceForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, Class<T> clazz);

    /**
     * key集合与otherKey集合的差集存储到destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param destRedisKeyBuild
     * @return
     */
    Long differenceForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild);

    /**
     * key集合与多个集合的差集存储到destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param destRedisKeyBuild
     * @return
     */
    Long differenceForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取集合所有元素
     *
     * @param redisKeyBuild
     * @param clazz
     * @return
     */
    <T> Set<T> membersForSet(RedisKeyBuild redisKeyBuild, Class<T> clazz);

    /**
     * 随机获取集合中的一个元素
     *
     * @param redisKeyBuild
     * @param clazz
     * @return
     */
    <T> T randomMemberForSet(RedisKeyBuild redisKeyBuild, Class<T> clazz);

    /**
     * 随机获取集合中count个元素
     *
     * @param redisKeyBuild
     * @param count
     * @param clazz
     * @return
     */
    <T> List<T> randomMembersForSet(RedisKeyBuild redisKeyBuild, long count, Class<T> clazz);

    /**
     * 随机获取集合中count个元素并且去除重复的
     *
     * @param redisKeyBuild
     * @param count
     * @param clazz
     * @return
     */
    <T> Set<T> distinctRandomMembersForSet(RedisKeyBuild redisKeyBuild, long count, Class<T> clazz);

    /**
     * 游标遍历
     * @param redisKeyBuild
     * @param options
     * @return
     */
    Cursor<String> scanForSet(RedisKeyBuild redisKeyBuild, ScanOptions options);



    /**------------------SortedSet相关操作--------------------------------*/

    /**
     * 存储有序列表
     *
     * @param redisKeyBuild key
     * @param value value
     * @param score 评分值
     * @return
     */
    void addForSortedSet(RedisKeyBuild redisKeyBuild, Object value, Double score);

    /**
     * 存储有序列表并设置超时时间(秒)
     *
     * @param redisKeyBuild key
     * @param value value
     * @param score 评分值
     * @param ttl 超时时间
     * @return
     */
    void addForSortedSet(RedisKeyBuild redisKeyBuild, Object value, Double score, long ttl);

    /**
     * 存储有序列表并设置超时时间
     *
     * @param redisKeyBuild key
     * @param value value
     * @param score 评分值
     * @param ttl 超时时间
     * @param timeUnit 时间单位
     * @return
     */
    void addForSortedSet(RedisKeyBuild redisKeyBuild, Object value, Double score, long ttl, TimeUnit timeUnit);

    /**
     * 存储有序列表
     *
     * @param redisKeyBuild
     * @param map map中的key如果是自定义对象类型需要重新equals和hashcode方法
     * @return
     */
    Long addForSortedSet(RedisKeyBuild redisKeyBuild, Map<?, Double> map);

    /**
     * 存储有序列表并设置超时时间(秒)
     *
     * @param redisKeyBuild
     * @param map map中的key如果是自定义对象类型需要重新equals和hashcode方法
     * @param ttl
     * @return
     */
    Long addForSortedSet(RedisKeyBuild redisKeyBuild, Map<?, Double> map, long ttl);

    /**
     * 存储有序列表并设置超时时间 自定义单位
     *
     * @param redisKeyBuild      key
     * @param map      map中的key如果是自定义对象类型需要重新equals和hashcode方法
     * @param ttl      过期时间
     * @param timeUnit 过期时间单位
     * @return 影响的条目
     */
    Long addForSortedSet(RedisKeyBuild redisKeyBuild, Map<?, Double> map, long ttl, TimeUnit timeUnit);

    /**
     * 获取有序列表中范围条目,并转为指定类型
     *
     * @param redisKeyBuild   key
     * @param start 开始下标 从0开始
     * @param end   结束下标 包含此条
     * @param clazz 序列化类型
     * @param <T>   泛型参数
     * @return 结果set集合
     */
    <T> Set<T> getRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz);

    /**
     * 反转获取有序列表中范围条目,并转为指定类型
     *
     * @param redisKeyBuild   key
     * @param start 开始下标 从0开始
     * @param end   结束下标 包含此条
     * @param clazz 序列化类型
     * @param <T>   泛型参数
     * @return 结果set集合
     */
    <T> Set<T> getReverseRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz);

    /**
     * 删除zSet条目
     *
     * @param redisKeyBuild   key
     * @param value 数据
     * @return 影响条目
     */
    Long delForSortedSet(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * 批量删除zSet条目
     *
     * @param redisKeyBuild             key
     * @param valueCollection 数据
     * @return 影响条目
     */
    Long delForSortedSet(RedisKeyBuild redisKeyBuild, Collection<?> valueCollection);

    /**
     * 删除范围元素
     *
     * @param redisKeyBuild   key
     * @param start 开始range
     * @param end   结束range
     * @return 影响条目
     */
    Long delRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end);


    /**
     * 增加元素的score值,并返回增加后的值
     *
     * @param redisKeyBuild key
     * @param value 对象
     * @param delta 值
     * @return 结果
     */
    Double incrementScoreForSortedSet(RedisKeyBuild redisKeyBuild, Object value, double delta);



    /**
     * 计算zSet总条数
     *
     * @param redisKeyBuild key
     * @return 总条数  不存在则空
     */
    Long sizeForSortedSet(RedisKeyBuild redisKeyBuild);

    /**
     * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
     *
     * @param redisKeyBuild   key
     * @param value value
     * @return rank
     */
    Long rankForSortedSet(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * 返回元素在集合的排名,按元素的score值由大到小排列
     *
     * @param redisKeyBuild
     * @param value
     * @return
     */
    Long reverseRankForSortedSet(RedisKeyBuild redisKeyBuild, Object value);


    /**
     * 获取集合元素, 并且把score值也获取
     *
     * @param redisKeyBuild
     * @param start
     * @param end
     * @param clazz
     * @return
     */
    <T> Set<ZSetOperations.TypedTuple<T>> rangeWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz);


    /**
     * 根据Score值查询集合元素
     *
     * @param redisKeyBuild
     * @param min
     *            最小值
     * @param max
     *            最大值
     * @param clazz
     * @return
     */
    <T> Set<T> rangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz);

    /**
     * 根据Score值查询集合元素(含有score值), 从小到大排序
     *
     * @param redisKeyBuild
     * @param min
     *            最小值
     * @param max
     *            最大值
     * @param clazz
     * @return
     */
    <T> Set<ZSetOperations.TypedTuple<T>> rangeByScoreWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz);


    /**
     * 根据Score值查询集合元素, 从小到大排序
     *
     * @param redisKeyBuild
     * @param min
     *            最小值
     * @param max
     *            最大值
     * @param start
     * @param end
     * @param clazz
     * @return
     */
    <T> Set<ZSetOperations.TypedTuple<T>> rangeByScoreWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max,
                                                                            long start, long end, Class<T> clazz);

    /**
     * 获取集合的元素, 从大到小排序, 并返回score值
     *
     * @param redisKeyBuild
     * @param start
     * @param end
     * @param clazz
     * @return
     */
    <T> Set<ZSetOperations.TypedTuple<T>> reverseRangeWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz);

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * @param redisKeyBuild
     * @param min
     * @param max
     * @param clazz
     * @return
     */
    <T> Set<T> reverseRangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz);

    /**
     * 根据Score值查询集合元素, 从大到小排序, 并返回score值
     *
     * @param redisKeyBuild
     * @param min
     * @param max
     * @param clazz
     * @return
     */
    <T> Set<ZSetOperations.TypedTuple<T>> reverseRangeByScoreWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz);

    /**
     * 根据Score值查询集合元素, 从大到小排序
     *
     * @param redisKeyBuild
     * @param min
     * @param max
     * @param start
     * @param end
     * @param clazz
     * @return
     */
    <T> Set<T> reverseRangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, long start, long end, Class<T> clazz);

    /**
     * 根据score值获取集合元素数量
     *
     * @param redisKeyBuild
     * @param min
     * @param max
     * @return
     */
    Long countForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max);

    /**
     * 获取集合大小
     *
     * @param redisKeyBuild
     * @return
     */
    Long zCardForSortedSet(RedisKeyBuild redisKeyBuild);

    /**
     * 获取集合中value元素的score值
     *
     * @param redisKeyBuild
     * @param value
     * @return
     */
    Double scoreByValueForSortedSet(RedisKeyBuild redisKeyBuild, Object value);

    /**
     * 移除指定索引位置的成员
     *
     * @param redisKeyBuild
     * @param start
     * @param end
     * @return
     */
    Long removeRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end);

    /**
     * 根据指定的score值的范围来移除成员
     *
     * @param redisKeyBuild
     * @param min
     * @param max
     * @return
     */
    Long removeRangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max);

    /**
     * 获取key和otherKey的并集并存储在destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param destRedisKeyBuild
     * @return
     */
    Long unionAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取key和otherKeys的并集并存储在destKey中
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param destRedisKeyBuild
     * @return
     */
    Long unionAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取key和otherKey的交集并存储在destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuild
     * @param destRedisKeyBuild
     * @return
     */
    Long intersectAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild);

    /**
     * 获取key和otherKeys的交集并存储在destKey中
     *
     * @param redisKeyBuild
     * @param otherRedisKeyBuilds
     * @param destRedisKeyBuild
     * @return
     */
    Long intersectAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild);

    /**
     * 游标遍历
     * @param redisKeyBuild
     * @param options
     * @return
     */
    Cursor<ZSetOperations.TypedTuple<String>> scanForSortedSet(RedisKeyBuild redisKeyBuild, ScanOptions options);

    /**
     * 不对外使用
     * @param redisKeyBuild
     * @param genericReturnType
     * @return
     */
    <T> T getByType(RedisKeyBuild redisKeyBuild, Type genericReturnType);
    /**
     * 获取实例
     *
     * @return
     */
    RedisTemplate getInstance();
}
java 复制代码
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/*
 * redis方法实现
 */
@AllArgsConstructor
public class RedisCacheImpl implements RedisCache {
    
    private StringRedisTemplate redisTemplate;

    @Override
    public <T> T get(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        // 如果取String类型 则直接取出返回
        String cachedValue = redisTemplate.opsForValue().get(key);
        if (String.class.isAssignableFrom(clazz)) {
            return (T) cachedValue;
        }
        return getComplex(cachedValue, clazz);
    }
    
    @Override
    public <T> T get(RedisKeyBuild redisKeyBuild, Class<T> clazz, Supplier<T> supplier, long ttl, TimeUnit timeUnit) {
        T t = get(redisKeyBuild, clazz);
        if (CacheUtil.isEmpty(t)) {
            t = supplier.get();
            if (CacheUtil.isEmpty(t)) {
                return null;
            }
            set(redisKeyBuild,t,ttl,timeUnit);
        }
        return t;
    }

    @Override
    public String getRange(RedisKeyBuild redisKeyBuild, long start, long end) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForValue().get(key, start, end);
    };

    @Override
    public <T> List<T> getValueIsList(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String valueStr = redisTemplate.opsForValue().get(key);
        if (StringUtil.isEmpty(valueStr)) {
            return new ArrayList<>();
        }
        return JSON.parseArray(valueStr, clazz);
    }
    
    @Override
    public <T> List<T> getValueIsList(RedisKeyBuild redisKeyBuild, Class<T> clazz, Supplier<List<T>> supplier, long ttl, TimeUnit timeUnit) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String valueStr = redisTemplate.opsForValue().get(key);
        List<T> tList = null;
        if (CacheUtil.isEmpty(valueStr)) {
            tList = supplier.get();
            if (CacheUtil.isEmpty(tList)) {
                return null;
            }
            set(redisKeyBuild,tList,ttl,timeUnit);
        }
        return tList;
    }


    @Override
    public List<String> getKeys(List<RedisKeyBuild> keyList) {
        CacheUtil.checkNotEmpty(keyList);
        List<String> batchKey = CacheUtil.getBatchKey(keyList);
        List<String> list = redisTemplate.opsForValue().multiGet(batchKey);
        
        return CacheUtil.optimizeRedisList(redisTemplate.opsForValue().multiGet(CacheUtil.optimizeRedisList(list)));
    }

    @Override
    public Boolean hasKey(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.hasKey(key);
    }

    @Override
    public Long getExpire(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.getExpire(key);
    }
    
    @Override
    public Long getExpire(RedisKeyBuild redisKeyBuild,TimeUnit timeUnit) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.getExpire(key,timeUnit);
    }

    @Override
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    @Override
    public Boolean move(RedisKeyBuild redisKeyBuild, int dbIndex) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.move(key, dbIndex);
    }

    @Override
    public Boolean persist(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.persist(key);
    }

    @Override
    public String randomKey() {
        return redisTemplate.randomKey();
    }

    @Override
    public void rename(RedisKeyBuild oldKey, RedisKeyBuild newKey) {
        CacheUtil.checkNotBlank(oldKey);
        CacheUtil.checkNotBlank(newKey);
        redisTemplate.rename(oldKey.getRelKey(), newKey.getRelKey());
    }

    @Override
    public Boolean renameIfAbsent(RedisKeyBuild oldKey, RedisKeyBuild newKey) {
        CacheUtil.checkNotBlank(oldKey);
        CacheUtil.checkNotBlank(newKey);
        return redisTemplate.renameIfAbsent(oldKey.getRelKey(), newKey.getRelKey());
    }

    @Override
    public DataType type(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.type(key);
    }
    
    @Override
    public void set(RedisKeyBuild redisKeyBuild, Object object) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String json = object instanceof String ? (String) object : JSON.toJSONString(object);
        redisTemplate.opsForValue().set(key, json);
    }

    @Override
    public void set(RedisKeyBuild redisKeyBuild, Object object, long ttl) {
        set(redisKeyBuild, object, ttl, CacheUtil.DEFAULT_TIME_UNIT);
    }

    @Override
    public void set(RedisKeyBuild redisKeyBuild, Object object, long ttl, TimeUnit timeUnit) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String json = object instanceof String ? (String) object : JSON.toJSONString(object);
        redisTemplate.opsForValue().set(key, json, ttl, timeUnit);
    }

    @Override
    public boolean setIfAbsent(RedisKeyBuild redisKeyBuild, Object object) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String json = object instanceof String ? (String) object : JSON.toJSONString(object);
        return redisTemplate.opsForValue().setIfAbsent(key, json);
    }

    @Override
    public Long size(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForValue().size(key);
    }

    @Override
    public void multiSet(Map<RedisKeyBuild, ?> map) {
        CacheUtil.checkNotEmpty(map);
        Map<String, String> mapForSave = new HashMap<>(map.size());
        map.forEach((hashKey, val) -> {
            String jsonValue = val instanceof String ? (String) val : JSON.toJSONString(val);
            mapForSave.put(hashKey.getRelKey(), jsonValue);
        });
        redisTemplate.opsForValue().multiSet(mapForSave);
    }

    @Override
    public boolean multiSetIfAbsent(Map<RedisKeyBuild, ?> map) {
        CacheUtil.checkNotEmpty(map);
        Map<String, String> mapForSave = new HashMap<>(map.size());
        map.forEach((hashKey, val) -> {
            String jsonValue = val instanceof String ? (String) val : JSON.toJSONString(val);
            mapForSave.put(hashKey.getRelKey(), jsonValue);
        });
        return redisTemplate.opsForValue().multiSetIfAbsent(mapForSave);
    }

    @Override
    public Long incrBy(RedisKeyBuild redisKeyBuild, long increment) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForValue().increment(key, increment);
    }

    @Override
    public Double incrByDouble(RedisKeyBuild redisKeyBuild, double increment) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForValue().increment(key, increment);
    }

    @Override
    public Integer append(RedisKeyBuild redisKeyBuild, String value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForValue().append(key, value);
    }

    @Override
    public void putHash(RedisKeyBuild redisKeyBuild, String hashKey, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        redisTemplate.opsForHash().put(key, hashKey, jsonValue);
    }

    @Override
    public void putHash(RedisKeyBuild redisKeyBuild, String hashKey, Object value, long ttl) {
        putHash(redisKeyBuild, hashKey, value, ttl, CacheUtil.DEFAULT_TIME_UNIT);
    }

    @Override
    public void putHash(RedisKeyBuild redisKeyBuild, String hashKey, Object value, long ttl, TimeUnit timeUnit) {
        putHash(redisKeyBuild, hashKey, value);
        // 设置过期时间
        expire(redisKeyBuild, ttl, timeUnit);
    }

    @Override
    public void putHash(RedisKeyBuild redisKeyBuild, Map<String, ?> map) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Map<String, String> mapForSave = new HashMap<>(map.size());
        map.forEach((hashKey, val) -> {
            String jsonValue = val instanceof String ? (String) val : JSON.toJSONString(val);
            mapForSave.put(hashKey, jsonValue);
        });
        redisTemplate.opsForHash().putAll(key, mapForSave);
    }

    @Override
    public void putHash(RedisKeyBuild redisKeyBuild, Map<String, ?> map, long ttl) {
        putHash(redisKeyBuild, map, ttl, CacheUtil.DEFAULT_TIME_UNIT);
    }

    @Override
    public void putHash(RedisKeyBuild redisKeyBuild, Map<String, ?> map, long ttl, TimeUnit timeUnit) {
        putHash(redisKeyBuild, map);
        expire(redisKeyBuild, ttl, timeUnit);
    }

    @Override
    public Boolean putHashIfAbsent(RedisKeyBuild redisKeyBuild, String hashKey, Object value){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForHash().putIfAbsent(key, hashKey, jsonValue);
    }

    @Override
    public <T> T getForHash(RedisKeyBuild redisKeyBuild, String hashKey, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        Object o = redisTemplate.opsForHash().get(key, hashKey);
        // 如果取String类型 则直接取出返回
        if (String.class.isAssignableFrom(clazz)) {
            return (T) o;
        }
        return getComplex(o, clazz);
    }

    @Override
    public <T> List<T> getValueIsListForHash(RedisKeyBuild redisKeyBuild, String hashKey, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        Object o = redisTemplate.opsForHash().get(key,hashKey);
        if (o == null) {
            return new ArrayList<>();
        }
        List<T> list = new ArrayList<>();
        if (o instanceof String) {
            list = JSON.parseArray((String)o, clazz);
        }
        return list;
    }

    @Override
    public <T> List<T> multiGetForHash(RedisKeyBuild redisKeyBuild, List<String> hashKeys, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKeys);
        String key = redisKeyBuild.getRelKey();
        List<Object> objHashKeys = new ArrayList<>(hashKeys);
        List<Object> multiGetObj = redisTemplate.opsForHash().multiGet(key, objHashKeys);
        
        if (CacheUtil.checkRedisListIsEmpty(multiGetObj)){
            return new ArrayList<>();
        }
        if (String.class.isAssignableFrom(clazz)) {
            return (List<T>) multiGetObj;
        }

        return parseObjects(multiGetObj, clazz);
    }

    @Override
    public <T> List<T> getAllForHash(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List<Object> valuesObj = redisTemplate.opsForHash().values(key);
        if (CacheUtil.checkRedisListIsEmpty(valuesObj)){
            return new ArrayList<>();
        }
        if (String.class.isAssignableFrom(clazz)) {
            return (List<T>) valuesObj;
        }

        return parseObjects(valuesObj, clazz);
    }
    
    @Override
    public <T> Map<String,T> getAllMapForHash(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
        Map<String,T> map = new HashMap<>(64);
        entries.forEach((k,v) -> {
            map.put(String.valueOf(k),getComplex(v, clazz));
        });
        return map;
    }

    @Override
    public <T> T indexForList(RedisKeyBuild redisKeyBuild, long index, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String cachedValue = redisTemplate.opsForList().index(key, index);
        if (StringUtil.isEmpty(cachedValue)) {
            return null;
        }
        if (String.class.isAssignableFrom(clazz)) {
            return (T) cachedValue;
        }
        return getComplex(cachedValue, clazz);
    }

    @Override
    public Long leftPushForList(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().leftPush(key, jsonValue);
    }

    @Override
    public Long leftPushAllForList(RedisKeyBuild redisKeyBuild, List<?> valueList){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(valueList);
        String key = redisKeyBuild.getRelKey();
        List<String> jsonList = new ArrayList<>(valueList.size());
        valueList.forEach(value -> {
            String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
            jsonList.add(jsonValue);
        });
        return redisTemplate.opsForList().leftPushAll(key, jsonList);
    }

    @Override
    public Long leftPushIfPresentForList(RedisKeyBuild redisKeyBuild, Object value){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().leftPushIfPresent(key, jsonValue);
    }

    @Override
    public Long leftPushForList(RedisKeyBuild redisKeyBuild, Object pivot, Object value){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(pivot);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonPivot = value instanceof String ? (String) pivot : JSON.toJSONString(pivot);
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().leftPush(key, jsonPivot, jsonValue);
    }

    @Override
    public Long rightPushForList(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().rightPush(key, jsonValue);
    }

    @Override
    public Long rightPushAllForList(RedisKeyBuild redisKeyBuild, List<Object> valueList){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(valueList);
        String key = redisKeyBuild.getRelKey();
        List<String> jsonList = new ArrayList<>(valueList.size());
        valueList.forEach(value -> {
            String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
            jsonList.add(jsonValue);
        });
        return redisTemplate.opsForList().rightPushAll(key, jsonList);
    }

    @Override
    public Long rightPushIfPresentForList(RedisKeyBuild redisKeyBuild, Object value){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().rightPushIfPresent(key, jsonValue);
    }

    @Override
    public Long rightPushForList(RedisKeyBuild redisKeyBuild, Object pivot, Object value){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(pivot);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonPivot = value instanceof String ? (String) pivot : JSON.toJSONString(pivot);
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().rightPush(key, jsonPivot, jsonValue);
    }

    @Override
    public void setForList(RedisKeyBuild redisKeyBuild, long index, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        redisTemplate.opsForList().set(key, index, jsonValue);
    }

    @Override
    public <T> T leftPopForList(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String s = redisTemplate.opsForList().leftPop(key);
        return getComplex(s, clazz);
    }

    @Override
    public <T> T leftPopBlockForList(RedisKeyBuild redisKeyBuild, Class<T> clazz, long timeout, TimeUnit unit) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String s = redisTemplate.opsForList().leftPop(key, timeout, unit);
        return getComplex(s, clazz);
    }

    @Override
    public <T> T rightPopForList(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String s = redisTemplate.opsForList().rightPop(key);
        return getComplex(s, clazz);
    }

    @Override
    public <T> T rightPopBlockForList(RedisKeyBuild redisKeyBuild, Class<T> clazz, long timeout, TimeUnit unit) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String s = redisTemplate.opsForList().rightPop(key, timeout, unit);
        return getComplex(s, clazz);
    }

    @Override
    public <T> T rightPopAndLeftPushForList(RedisKeyBuild sourceKey, RedisKeyBuild destinationKey, Class<T> clazz) {
        CacheUtil.checkNotBlank(sourceKey);
        CacheUtil.checkNotBlank(destinationKey);
        String sourceRelKey = sourceKey.getRelKey();
        String destinationRelKey = destinationKey.getRelKey();
        String s = redisTemplate.opsForList().rightPopAndLeftPush(sourceRelKey, destinationRelKey);
        return getComplex(s, clazz);
    }

    @Override
    public <T> T rightPopBlockAndLeftPushForList(RedisKeyBuild sourceKey, RedisKeyBuild destinationKey, Class<T> clazz, long timeout, TimeUnit unit) {
        CacheUtil.checkNotBlank(sourceKey);
        CacheUtil.checkNotBlank(destinationKey);
        String sourceRelKey = sourceKey.getRelKey();
        String destinationRelKey = destinationKey.getRelKey();
        String s = redisTemplate.opsForList().rightPopAndLeftPush(sourceRelKey, destinationRelKey, timeout, unit);
        return getComplex(s, clazz);
    }

    @Override
    public <T> List<T> getAllForList(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List list = redisTemplate.opsForList().range(key, 0, -1);
        if (CacheUtil.checkRedisListIsEmpty(list)){
            return new ArrayList<>();
        }
        return parseObjects(list, clazz);
    }

    @Override
    public <T> List<T> rangeForList(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz){
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List range = redisTemplate.opsForList().range(key, start, end);
        if (CacheUtil.checkRedisListIsEmpty(range)){
            return new ArrayList<>();
        }
        return parseObjects(range, clazz);
    }

    @Override
    public Long removeForList(RedisKeyBuild redisKeyBuild, long index, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForList().remove(key, index, jsonValue);
    }

    @Override
    public void trimForList(RedisKeyBuild redisKeyBuild, long start, long end) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        redisTemplate.opsForList().trim(key, start, end);
    }

    @Override
    public Long lenForList(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForList().size(key);
    }

    @Override
    public Boolean hasKeyForHash(RedisKeyBuild redisKeyBuild, String hashKey) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    @Override
    public void del(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        redisTemplate.delete(key);
    }
    

    @Override
    public Long delForHash(RedisKeyBuild redisKeyBuild, String hashKey) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForHash().delete(key, hashKey);
    }

    @Override
    public Long delForHash(RedisKeyBuild redisKeyBuild, Collection<String> hashKeys) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKeys);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForHash().delete(key, hashKeys.toArray());
    }

    @Override
    public Long incrByForHash(RedisKeyBuild redisKeyBuild, String hashKey, long increment) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForHash().increment(key, hashKey, increment);
    }

    @Override
    public Double incrByDoubleForHash(RedisKeyBuild redisKeyBuild, String hashKey, double delta){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(hashKey);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForHash().increment(key, hashKey, delta);
    }

    @Override
    public Set<String> hashKeysForHash(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<Object> keys = redisTemplate.opsForHash().keys(key);
        return parseObjects(keys,String.class);
    }

    @Override
    public Long sizeForHash(RedisKeyBuild redisKeyBuild){
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForHash().size(key);
    }

    @Override
    public void del(Collection<RedisKeyBuild> keys) {
        CacheUtil.checkNotEmpty(keys);
        List<String> batchKey = CacheUtil.getBatchKey(keys);
        redisTemplate.delete(batchKey);
    }

    @Override
    public Boolean expire(RedisKeyBuild redisKeyBuild, long ttl, TimeUnit timeUnit) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.expire(key, ttl, timeUnit);
    }

    @Override
    public Long addForSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForSet().add(key, jsonValue);
    }

    @Override
    public Long addForSet(RedisKeyBuild redisKeyBuild, List<?> values) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(values);
        String key = redisKeyBuild.getRelKey();
        List<String> jsonList = new ArrayList<>(values.size());
        values.forEach(value -> {
            String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
            jsonList.add(jsonValue);
        });
        return redisTemplate.opsForSet().add(key, jsonList.toArray(new String[]{}));
    }

    @Override
    public Long removeForSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForSet().remove(key, jsonValue);
    }

    @Override
    public Long removeForSet(RedisKeyBuild redisKeyBuild, List<?> values) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(values);
        String key = redisKeyBuild.getRelKey();
        List<String> jsonList = values.stream()
                .map(value -> value instanceof String ? (String) value : JSON.toJSONString(value))
                .collect(Collectors.toList());
        return redisTemplate.opsForSet().remove(key, jsonList.toArray(new String[]{}));
    }

    @Override
    public <T> T popForSet(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String cachedValue = redisTemplate.opsForSet().pop(key);
        return getComplex(cachedValue,clazz);
    }

    @Override
    public boolean moveForSet(RedisKeyBuild redisKeyBuild, Object value, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String destKey = destRedisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForSet().move(key, jsonValue, destKey);
    }

    @Override
    public Long sizeForSet(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().size(key);
    }

    @Override
    public Boolean isMemberForSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForSet().isMember(key, jsonValue);
    }

    @Override
    public <T> Set<T> intersectForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForSet().intersect(key, otherKey);
        return parseObjects(set,clazz);
    }

    @Override
    public <T> Set<T> intersectForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        Set set = redisTemplate.opsForSet().intersect(key, otherKeys);
        return parseObjects(set,clazz);
    }

    @Override
    public Long intersectAndStoreForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey);
    }

    @Override
    public Long intersectAndStoreForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey);
    }

    @Override
    public <T> Set<T> unionForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForSet().union(key, otherKey);
        return parseObjects(set,clazz);
    }

    @Override
    public <T> Set<T> unionForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        Set set = redisTemplate.opsForSet().union(key, otherKeys);
        return parseObjects(set,clazz);
    }

    @Override
    public Long unionAndStoreForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey);
    }

    @Override
    public Long unionAndStoreForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey);
    }

    @Override
    public <T> Set<T> differenceForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForSet().difference(key, otherKey);
        return parseObjects(set,clazz);
    }

    @Override
    public <T> Set<T> differenceForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        Set set = redisTemplate.opsForSet().difference(key, otherKeys);
        return parseObjects(set,clazz);
    }

    @Override
    public Long differenceForSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey);
    }

    @Override
    public Long differenceForSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForSet().differenceAndStore(key, otherKeys, destKey);
    }

    @Override
    public <T> Set<T> membersForSet(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set members = redisTemplate.opsForSet().members(key);
        return parseObjects(members,clazz);
    }

    @Override
    public <T> T randomMemberForSet(RedisKeyBuild redisKeyBuild, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String s = redisTemplate.opsForSet().randomMember(key);
        return getComplex(s, clazz);
    }

    @Override
    public <T> List<T> randomMembersForSet(RedisKeyBuild redisKeyBuild, long count, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List list = redisTemplate.opsForSet().randomMembers(key, count);
        if (CacheUtil.checkRedisListIsEmpty(list)){
            return new ArrayList<>();
        }
        return parseObjects(list,clazz);
    }

    @Override
    public <T> Set<T> distinctRandomMembersForSet(RedisKeyBuild redisKeyBuild, long count, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForSet().distinctRandomMembers(key, count);
        return parseObjects(set,clazz);
    }

    @Override
    public Cursor<String> scanForSet(RedisKeyBuild redisKeyBuild, ScanOptions options) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Cursor<String> scan = redisTemplate.opsForSet().scan(key, options);
        return scan;
    }

    @Override
    public void addForSortedSet(RedisKeyBuild redisKeyBuild, Object value, Double score){
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        CacheUtil.checkNotEmpty(score);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        redisTemplate.opsForZSet().add(key,jsonValue,score);
    }

    @Override
    public void addForSortedSet(RedisKeyBuild redisKeyBuild, Object value, Double score, long ttl){
        addForSortedSet(redisKeyBuild,value,score,ttl, CacheUtil.DEFAULT_TIME_UNIT);
    }

    @Override
    public void addForSortedSet(RedisKeyBuild redisKeyBuild, Object value, Double score, long ttl, TimeUnit timeUnit){
        addForSortedSet(redisKeyBuild,value,score);
        expire(redisKeyBuild, ttl, timeUnit);
    }

    @Override
    public Long addForSortedSet(RedisKeyBuild redisKeyBuild, Map<?, Double> map) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<ZSetOperations.TypedTuple<String>> collect =
                map.entrySet()
                        .stream()
                        .map(item -> {
                            String entryKey = item.getKey() instanceof String ? (String) item.getKey() : JSON.toJSONString(item.getKey());
                            return new DefaultTypedTuple<>(entryKey, item.getValue());
                        })
                        .collect(Collectors.toSet());
        return redisTemplate.opsForZSet().add(key, collect);
    }

    @Override
    public Long addForSortedSet(RedisKeyBuild redisKeyBuild, Map<?, Double> map, long ttl) {
        return addForSortedSet(redisKeyBuild, map, ttl, CacheUtil.DEFAULT_TIME_UNIT);
    }

    @Override
    public Long addForSortedSet(RedisKeyBuild redisKeyBuild, Map<?, Double> map, long ttl, TimeUnit timeUnit) {
        Long count = addForSortedSet(redisKeyBuild, map);
        expire(redisKeyBuild, ttl, timeUnit);
        return count;
    }

    @Override
    public <T> Set<T> getRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set resultSet = redisTemplate.opsForZSet().range(key, start, end);
        return parseObjects(resultSet,clazz);
    }

    @Override
    public <T> Set<T> getReverseRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set resultSet = redisTemplate.opsForZSet().reverseRange(key, start, end);
        return parseObjects(resultSet,clazz);
    }

    @Override
    public Long delForSortedSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForZSet().remove(key, jsonValue);
    }

    @Override
    public Long delForSortedSet(RedisKeyBuild redisKeyBuild, Collection<?> valueCollection) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(valueCollection);
        String key = redisKeyBuild.getRelKey();
        List<String> jsonValueList = valueCollection.stream()
                .map(value -> value instanceof String ? (String) value : JSON.toJSONString(value))
                .distinct()
                .collect(Collectors.toList());
        return redisTemplate.opsForZSet().remove(key,jsonValueList.toArray());
    }

    @Override
    public Long delRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().removeRange(key, start, end);
    }

    @Override
    public Double incrementScoreForSortedSet(RedisKeyBuild redisKeyBuild, Object value, double delta) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForZSet().incrementScore(key, jsonValue, delta);
    }

    @Override
    public Long sizeForSortedSet(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().size(key);
    }

    @Override
    public Long rankForSortedSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForZSet().rank(key, jsonValue);
    }

    @Override
    public Long reverseRankForSortedSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForZSet().reverseRank(key, jsonValue);
    }

    @Override
    public <T> Set<ZSetOperations.TypedTuple<T>> rangeWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<ZSetOperations.TypedTuple<String>> cacheSet = redisTemplate.opsForZSet().rangeWithScores(key, start, end);
        if (cacheSet == null) {
            return new HashSet<>();
        }
        return typedTupleStringParseObjects(cacheSet, clazz);
    }

    @Override
    public <T> Set<T> rangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForZSet().rangeByScore(key, min, max);
        return parseObjects(set,clazz);
    }

    @Override
    public <T> Set<ZSetOperations.TypedTuple<T>> rangeByScoreWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<ZSetOperations.TypedTuple<String>> cacheSet = redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
        return typedTupleStringParseObjects(cacheSet, clazz);
    }

    @Override
    public <T> Set<ZSetOperations.TypedTuple<T>> rangeByScoreWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max,
                                                                                   long start, long end, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<ZSetOperations.TypedTuple<String>> cacheSet = redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, start, end);
        return typedTupleStringParseObjects(cacheSet, clazz);
    }

    @Override
    public <T> Set<ZSetOperations.TypedTuple<T>> reverseRangeWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<ZSetOperations.TypedTuple<String>> cacheSet = redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
        return typedTupleStringParseObjects(cacheSet, clazz);
    }

    @Override
    public <T> Set<T> reverseRangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
        return parseObjects(set,clazz);
    }

    @Override
    public <T> Set<ZSetOperations.TypedTuple<T>> reverseRangeByScoreWithScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set<ZSetOperations.TypedTuple<String>> cacheSet = redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max);
        return typedTupleStringParseObjects(cacheSet, clazz);
    }

    @Override
    public <T> Set<T> reverseRangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max, long start, long end, Class<T> clazz) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        Set set = redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end);
        return parseObjects(set, clazz);
    }

    @Override
    public Long countForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().count(key, min, max);
    }

    @Override
    public Long zCardForSortedSet(RedisKeyBuild redisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().zCard(key);
    }

    @Override
    public Double scoreByValueForSortedSet(RedisKeyBuild redisKeyBuild, Object value) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(value);
        String key = redisKeyBuild.getRelKey();
        String jsonValue = value instanceof String ? (String) value : JSON.toJSONString(value);
        return redisTemplate.opsForZSet().score(key, jsonValue);
    }

    @Override
    public Long removeRangeForSortedSet(RedisKeyBuild redisKeyBuild, long start, long end) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().removeRange(key, start, end);
    }

    @Override
    public Long removeRangeByScoreForSortedSet(RedisKeyBuild redisKeyBuild, double min, double max) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
    }

    @Override
    public Long unionAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey);
    }

    @Override
    public Long unionAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().unionAndStore(key, otherKeys, destKey);
    }

    @Override
    public Long intersectAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, RedisKeyBuild otherRedisKeyBuild, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotBlank(otherRedisKeyBuild);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        String otherKey = otherRedisKeyBuild.getRelKey();
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey);
    }

    @Override
    public Long intersectAndStoreForSortedSet(RedisKeyBuild redisKeyBuild, Collection<RedisKeyBuild> otherRedisKeyBuilds, RedisKeyBuild destRedisKeyBuild) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        CacheUtil.checkNotEmpty(otherRedisKeyBuilds);
        CacheUtil.checkNotBlank(destRedisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        List<String> otherKeys = CacheUtil.getBatchKey(otherRedisKeyBuilds);
        String destKey = destRedisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey);
    }

    @Override
    public Cursor<ZSetOperations.TypedTuple<String>> scanForSortedSet(RedisKeyBuild redisKeyBuild, ScanOptions options) {
        CacheUtil.checkNotBlank(redisKeyBuild);
        String key = redisKeyBuild.getRelKey();
        return redisTemplate.opsForZSet().scan(key, options);
    }

    @Override
    public <T> T getByType(RedisKeyBuild redisKeyBuild, Type genericReturnType){
        String key = redisKeyBuild.getRelKey();
        String s = redisTemplate.boundValueOps(key).get();
        if (StringUtil.isEmpty(s)) {
            return null;
        }
        return JSONObject.parseObject(s ,genericReturnType);
    }

    @Override
    public RedisTemplate getInstance() {
        return redisTemplate;
    }


    public <T> T getComplex(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }
        if (clazz.isAssignableFrom(String.class)) {
            if (source instanceof String) {
                return (T)source;
            }else{
                return (T)JSON.toJSONString(source);
            }
        }
        return source instanceof String ? JSON.parseObject((String) source, CacheUtil.buildType(clazz)) : null;
    }

    public <T> List<T> parseObjects(List<Object> sources, Class<T> clazz) {
        if (sources == null) {
            return new ArrayList<>();
        }
        if (clazz.isAssignableFrom(String.class)) {
            List<T> resultList = (List<T>) sources.stream()
                    .filter(Objects::nonNull)
                    .map(each -> each instanceof String ? (String) each : JSON.toJSONString(each))
                    .collect(Collectors.toList());
            return resultList;
        }
        List<T> resultList = (List<T>) sources.stream()
                .filter(Objects::nonNull)
                .map(each -> each instanceof String ? JSON.parseObject((String) each, CacheUtil.buildType(clazz)) : null)
                .collect(Collectors.toList());
        return resultList;
    }

    public <T> Set<T> parseObjects(Set<Object> sources, Class<T> clazz) {
        if (sources == null) {
            return new HashSet<>();
        }
        if (clazz.isAssignableFrom(String.class)) {
            Set<T> resultSet = (Set<T>) sources.stream()
                    .map(each -> each instanceof String ? (String) each : JSON.toJSONString(each))
                    .collect(Collectors.toSet());
            return resultSet;
        }
        Set<T> resultSet = (Set<T>) sources.stream()
                .map(each -> each instanceof String ? JSON.parseObject((String) each, CacheUtil.buildType(clazz)) : null)
                .collect(Collectors.toSet());
        return resultSet;
    }

    public <T> Set<ZSetOperations.TypedTuple<T>> typedTupleStringParseObjects(Set<ZSetOperations.TypedTuple<String>> sources, Class<T> clazz){
        if (sources == null) {
            return new HashSet<>();
        }
        Set<ZSetOperations.TypedTuple<T>> set = new HashSet<>(sources.size());
        for (ZSetOperations.TypedTuple<String> typedTuple : sources) {
            String value = typedTuple.getValue();
            T complex = getComplex(value, clazz);
            Double score = typedTuple.getScore();
            DefaultTypedTuple defaultTypedTuple = new DefaultTypedTuple(complex,score);
            set.add(defaultTypedTuple);
        }
        return set;
    }

    public <T> Set<ZSetOperations.TypedTuple<T>> typedTupleParseObjects(Set<ZSetOperations.TypedTuple> sources, Class<T> clazz){
        if (sources == null) {
            return new HashSet<>();
        }
        Set<ZSetOperations.TypedTuple<T>> set = new HashSet<>(sources.size());
        for (ZSetOperations.TypedTuple typedTuple : sources) {
            Object value = typedTuple.getValue();
            T complex = getComplex(value, clazz);
            Double score = typedTuple.getScore();
            DefaultTypedTuple defaultTypedTuple = new DefaultTypedTuple(complex,score);
            set.add(defaultTypedTuple);
        }
        return set;
    }
}
java 复制代码
import com.alibaba.fastjson.util.ParameterizedTypeImpl;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/*
 * 缓存对象映射工具
 */
public class CacheUtil {

    public static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;

    /**
     * 构建类型
     *
     * @param types
     * @return
     */
    public static Type buildType(Type... types) {
        ParameterizedTypeImpl beforeType = null;
        if (types != null && types.length > 0) {
            if (types.length == 1) {
                return new ParameterizedTypeImpl(new Type[]{null}, null,
                        types[0]);
            }

            for (int i = types.length - 1; i > 0; i--) {
                beforeType = new ParameterizedTypeImpl(new Type[]{beforeType == null ? types[i] : beforeType}, null,
                        types[i - 1]);
            }
        }
        return beforeType;
    }

    /**
     * 检查 Key 是否为空或空的字符串
     *
     * @param key
     */
    public static void checkNotBlank(String... key) {
        for (String s : key) {
            if (StringUtil.isEmpty(s)) {
                throw new RuntimeException("请求参数缺失");
            }
        }
    }

    /**
     * 检查 redisKeyBuild 中的key是否为空或空的字符串
     *
     * @param redisKeyBuild key包装
     */
    public static void checkNotBlank(RedisKeyBuild redisKeyBuild) {
        if (StringUtil.isEmpty(redisKeyBuild.getRelKey())) {
            throw new RuntimeException("请求参数缺失");
        }
    }

    /**
     * 检查 list 是否为空或空的字符串
     *
     * @param list
     */
    public static void checkNotBlank(Collection<String> list) {
        for (String s : list) {
            if (StringUtil.isEmpty(s)) {
                throw new RuntimeException("请求参数缺失");
            }
        }
    }

    /**
     * 检查 list 是否为空或空的字符串
     *
     * @param list key集合
     */
    public static void checkNotEmpty(Collection<?> list) {
        for (Object o : list) {
            if (o == null) {
                throw new RuntimeException("请求参数缺失");
            }
        }
    }

    /**
     * 检查 object 是否为空
     *
     * @param object
     */
    public static void checkNotEmpty(Object object) {
        if (isEmpty(object)) {
            throw new RuntimeException("请求参数缺失");
        }
    }
    
    /**
     * 判断 object 是否为空
     *
     */
    public static boolean isEmpty(Object object) {
        if (object == null) {
            return true;
        }
        if (object instanceof String) {
            return StringUtil.isEmpty((String) object);
        }
        if (object instanceof Collection) {
            return ((Collection<?>) object).isEmpty();
        }
        return false;
    }

    public static List<String> getBatchKey(Collection<RedisKeyBuild> list){
        return list.stream().map(RedisKeyBuild::getRelKey).collect(Collectors.toList());
    }

    public static <T> List<T> optimizeRedisList(List<T> list){
        if (Objects.isNull(list)) {
            return new ArrayList<>();
        }
        if (list.size() == 0 || Objects.isNull(list.get(0))) {
            return new ArrayList<>();
        }
        return list;
    }
    
    public static boolean checkRedisListIsEmpty(List<?> list){
        if (Objects.isNull(list)) {
            return true;
        }
        return list.size() == 0 || Objects.isNull(list.get(0));
    }
}

字符串方法:

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/*
 * String工具
 */
public class StringUtil {
	private final static Logger logger = LoggerFactory.getLogger(StringUtil.class);

	/**
	 * 判断字符串不为空
	 * @param str 字符串
	 * @return
	 */
	public static boolean isNotEmpty(String str) {
		return (str != null && !str.isEmpty() && !str.trim().isEmpty() && !"null".equalsIgnoreCase(str.trim())
				&& !"undefined".equalsIgnoreCase(str.trim()) && !"NULL".equalsIgnoreCase(str.trim()));

	}

	/**
	 * 判断字符串为空
	 * @param str	字符串
	 * @return
	 */
	public static boolean isEmpty(String str) {
		return !StringUtil.isNotEmpty(str);
	}
	
	/**
	 * 将流转换为字符串
	 * @param is 文件流
	 * @return
	 */
	public static String inputStreamConvertString(InputStream is){
		ByteArrayOutputStream baos = null;
		String result = null;
		try {
			if(is != null) {
				baos = new ByteArrayOutputStream();
				int i;
				while ((i = is.read()) != -1) {
					baos.write(i);
				}
				result = baos.toString();
			}
		}catch(IOException e) {
			throw new RuntimeException("流转换为字符串失败!");
		}finally {
			if(baos != null) {
				try {
					baos.close();
				} catch (IOException e) {
					logger.error("关闭流失败!");
				}
			}
		}
		return result;
	}
	
	/**
	 * 将URL参数转成map
	 * */
	public static Map<String, String> convertQueryStringToMap(String queryString) {
		Map<String, String> resultMap = new HashMap<>(256);
		String[] params = queryString.split("&");
		for (String param : params) {
			String[] keyValue = param.split("=");
			if (keyValue.length == 2) {
				try {
					String key = java.net.URLDecoder.decode(keyValue[0], "UTF-8");
					String value = java.net.URLDecoder.decode(keyValue[1], "UTF-8");
					resultMap.put(key, value);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return resultMap;
	}
}

如何使用?

java 复制代码
public enum RedisKeyEnum {
    Key("key","键值测试","value为TestCacheDto类型","lk"),
    Key2("key:%s","键值占位测试","value为TestCacheDto类型","lk"),
    CHANNEL_DATA("channel_data:%s","channel_data的key","channel_data的value","k"),
}
java 复制代码
@Autowired
private RedisCache redisCache;

private GetChannelDataVo getChannelDataByRedis(String code){
    return redisCache.get(RedisKeyBuild.createRedisKey(RedisKeyManage.CHANNEL_DATA,code),GetChannelDataVo.class);
}
相关推荐
短剑重铸之日2 小时前
《7天学会Redis》Day 5 - Redis Cluster集群架构
数据库·redis·后端·缓存·架构·cluster
007php0072 小时前
mySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据
数据库·redis·git·mysql·面试·职场和发展·php
lkbhua莱克瓦242 小时前
进阶-存储过程3-存储函数
java·数据库·sql·mysql·数据库优化·视图
计算机程序设计小李同学2 小时前
基于SSM框架的动画制作及分享网站设计
java·前端·后端·学习·ssm
鱼跃鹰飞2 小时前
JMM 三大特性(原子性 / 可见性 / 有序性)面试精简版
java·jvm·面试
该怎么办呢3 小时前
基于cesium的三维不动产登记系统的设计与实现(毕业设计)
java·毕业设计
win x3 小时前
Redis 分布式锁
数据库·redis·分布式
J不A秃V头A3 小时前
多任务执行时,共享请求对象被并发修改
java
heartbeat..3 小时前
零基础学 SQL:DQL/DML/DDL/DCL 核心知识点汇总(附带连接云服务器数据库教程)
java·服务器·数据库·sql