SpringBoot整合Redis

SpringBoot整合Redis

Pom依赖

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--连接池-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<!--json-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.9</version>
</dependency>

RedisConfig

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        // 创建Template
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key和 hashKey采用 string序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value和 hashValue采用 JSON序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
}

application.yaml

spring:
  application:
    name: common-demo
  redis:
    host: 127.0.0.1
    port: 6379
    lettuce:
      pool:
        max-active: 8 # 最大连接数
        max-idle: 8 # 最大空闲连接数
        max-wait: 100 #连接等待时间

RedisUtil

/**
 * @author czk
 * @since 2022/12/17
 */
@Component
@SuppressWarnings(value = "all")
public class RedisUtil {
    @Resource
    RedisTemplate redisTemplate;
    private static final String separator = ":";

    // TODO:生成一个Key

    /**
     * 生成一个带浅醉的key,分隔符为:
     * @param prefix 前缀
     * @param key key值
     * @param <K> key
     * @return String类型的key
     */
    public static <K> String generateKey(String prefix, K key) {
        return prefix + separator + key;
    }

    /**
     * 生成一个带浅醉的key,分隔符为:
     * @param key key值
     * @param <K> key
     * @return String类型的key
     */
    public static <K> String generateKey(K key) {
        return key.toString();
    }

    /**
     * 生成若干个带浅醉的key,分隔符为:
     * @param prefix 前缀
     * @param key key值
     * @param <K> key
     * @return String类型的key
     */
    public static <K> String[] generateKeys(String prefix, K... keys) {
        String[] strings = Arrays.stream(keys).map(e -> {
            return prefix + separator + e;
        }).toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[keys.length];
            }
        });
        return strings;
    }

    /**
     * 生成若干个带浅醉的key,分隔符为:
     * @param key key值
     * @param <K> key
     * @return String类型的key
     */
    public static <K> String[] generateKeys(K... keys) {
        String[] strings = Arrays.stream(keys).map(e->{ return e.toString();}).toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[keys.length];
            }
        });
        return strings;
    }

    // TODO: 自定义 redis 操作

    /**
     * 操作字符串:自主操作,
     * 如: redisUtil.operateString().set(...)
     *
     * @return 返回ValueOperations,用于操作String类型
     */
    public <K, V> ValueOperations<K, V> operateString() {
        return redisTemplate.opsForValue();
    }

    /**
     * 操作哈希:自主操作,
     * 如: redisUtil.operateHash().put(...)
     *
     * @return 返回HashOperations,用于操作Hash类型
     */
    public <H, K, V> HashOperations<H, K, V> operateHash() {
        return redisTemplate.opsForHash();
    }

    /**
     * 操作队列:自主操作,
     * 如: redisUtil.operateList().leftPush(...)
     *
     * @return 返回ListOperations,用于操作List类型
     */
    public <K, V> ListOperations<K, V> operateList() {
        return redisTemplate.opsForList();
    }

    /**
     * 操作Set集合:自主操作,
     * 如: redisUtil.operateSet().leftPush(...)
     *
     * @return 返回SetOperations,用于操作Set类型
     */
    public <K, V> SetOperations<K, V> operateSet() {
        return redisTemplate.opsForSet();
    }

    /**
     * 操作有序Set集合:自主操作,
     * 如: redisUtil.operateSortSet().leftPush(...)
     *
     * @return 返回ZSetOperations,用于操作SortSet类型
     */
    public <K, V> ZSetOperations<K, V> operateSortSet() {
        return redisTemplate.opsForZSet();
    }


    /**
     * 操作GEO类型数据
     *
     * @param <K> 泛型
     * @param <M> 泛型
     * @return 返回GeoOperations, 用于操作GEO数据
     */
    public <K, M> GeoOperations operateGeo() {
        return redisTemplate.opsForGeo();
    }

    /**
     * 用于操作Cluster类型
     *
     * @param <K> 泛型
     * @param <V> 泛型
     * @return ClusterOperations
     * 提示:redis集群相关,工具类将不提供Cluster的操作方法,需要的请自行调用本方法执行
     */
    public <K, V> ClusterOperations operateCluster() {
        return redisTemplate.opsForCluster();
    }

    /**
     * 用于操作HyperLogLog类型
     *
     * @param <K> 泛型
     * @param <V> 泛型
     * @return HyperLogLogOperations
     * HyperLogLog是用来做基数统计的数据结构,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的,无返回值
     * add(统计数key,统计元素)
     * size(统计数key(可以一个或多个统计数key)),返回不重复元素个数
     * delete(统计数key),移除该统计数
     * union(新统计数key,若干个旧统计数key),合并成一个新的统计数,并返回该统计数中不重复元素个数
     */
    public <K, V> HyperLogLogOperations operateHyperLogLog() {
        return redisTemplate.opsForHyperLogLog();
    }

    /**
     * 用于操作StreamOperations类型
     *
     * @param <K> 泛型
     * @param <V> 泛型
     * @return StreamOperations
     * 提示:消息队列相关(致命缺点,消息无法持久化),工具类将不提供StreamOperations的操作方法,需要的请自行调用本方法执行
     */
    public <HK, HV> StreamOperations operateStream() {
        return redisTemplate.opsForStream();
    }

    // TODO: key 操作 : 过期设置、存在判断

    /**
     * key存在时,为key设置超时时间,返回true,否则返回false
     *
     * @param key      redis中的key
     * @param timeout  超时时间
     * @param timeUnit 超时单位
     * @return 是否设置成功
     */
    public <K> boolean expire(K key, Long timeout, TimeUnit timeUnit) {
        return redisTemplate.expire(key, timeout, timeUnit);
    }

    /**
     * key存在时,为key设置超时时间,返回true,否则返回false
     *
     * @param key      redis中的key
     * @param duration 超时时间
     * @return 是否设置成功
     */
    public <K> boolean expire(K key, Duration duration) {
        return redisTemplate.expire(key, duration);
    }

    /**
     * 设置 key 过期的具体日期
     *
     * @param key  redis中的key
     * @param date 指定超时时间
     * @return 是否设置成功
     */
    public <K> boolean expiredAt(K key, Date date) {
        return redisTemplate.expireAt(key, date);
    }

    /**
     * 设置 key 过期的具体时间
     *
     * @param key     redis中的key
     * @param instant 指定超时时间
     * @return 是否设置成功
     */
    public <K> boolean expiredAt(K key, Instant instant) {
        return redisTemplate.expireAt(key, instant);
    }

    /**
     * 获取key的超时时间,key不存在返回负数(-2)
     *
     * @param key redis中的key
     * @return 剩余时间
     */
    public <K> Long getExpire(K key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 获取key的超时时间,key不存在返回负数(-2)
     *
     * @param key      redis中的key
     * @param timeUnit 时间单位
     * @return 获取剩余过期时间
     */
    public <K> Long getExpired(K key, TimeUnit timeUnit) {
        return redisTemplate.getExpire(key, timeUnit);
    }

    /**
     * 判断Redis中是否存在指定的Key
     *
     * @param key redis中的key
     * @return 是否存在指定key
     */
    public <K> boolean hasKey(K key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 删除单个key
     *
     * @param key redis中的key
     * @return 是否删除成功
     */
    public <K> boolean delKey(K key) {
        return redisTemplate.delete(key);
    }

    /**
     * 删除多个key,返回删除个数
     *
     * @param keys redis中的key
     * @return 删除key的个数
     */
    public <K> Long delKeys(Collection<K> keys) {
        return redisTemplate.delete(keys);
    }

    // TODO: String类型的相关操作

    /**
     * String类型操作,无规定超时时间
     *
     * @param key   redis中的key
     * @param value 对应key的值
     */
    public <K, V> void setString(K key, V value) {
        this.operateString().set(key, value);
    }

    /**
     * String类型操作,规定超时时间,TimeUnit
     *
     * @param key      redis中的key
     * @param value    对应key的值
     * @param timeout  超时时间
     * @param timeUnit 时间单位
     */
    public <K, V> void setStringWithExpired(K key, V value, Long timeout, TimeUnit timeUnit) {
        if (timeUnit != null) {
            this.operateString().set(key, value, timeout, timeUnit);
            return;
        } else {
            this.operateString().set(key, value, timeout, TimeUnit.SECONDS);
        }
    }

    /**
     * String类型操作,规定超时时间,Duration
     *
     * @param key      redis中的key
     * @param value    对应key的值
     * @param duration 超时时间
     */
    public <K, V> void setStringWithExpiredDuration(K key, V value, Duration duration) {
        this.operateString().set(key, value, duration);
    }

    /**
     * String类型操作,如果存在则返回false,不存在则返回true
     *
     * @param key   redis中的key
     * @param value 对应key的值
     * @return 设置是否成功
     */
    public <K, V> boolean setStringIfAbsent(K key, V value) {
        return this.operateString().setIfAbsent(key, value);
    }

    /**
     * String类型操作,规定超时时间,TimeUnit
     *
     * @param key      redis中的key
     * @param value    对应key的值
     * @param timeout  超时时间
     * @param timeUnit 时间单位
     */
    public <K, V> boolean setStringWithExpiredIfAbsent(K key, V value, Long timeout, TimeUnit timeUnit) {
        if (timeUnit != null) {
            return this.operateString().setIfAbsent(key, value, timeout, timeUnit);
        } else {
            return this.operateString().setIfAbsent(key, value, timeout, TimeUnit.SECONDS);
        }
    }

    /**
     * String类型操作,规定超时时间,Duration
     *
     * @param key      redis中的key
     * @param value    对应key的值
     * @param duration 超时时间
     */
    public <K, V> boolean setStringWithExpiredDurationIfAbsent(K key, V value, Duration duration) {
        return this.operateString().setIfAbsent(key, value, duration == null ? Duration.ofSeconds(60) : duration);
    }

    /**
     * 通过 key 获取 String
     *
     * @param key redis中的key
     * @return 返回指定key的值
     */
    public <K> Object getString(K key) {
        return this.operateString().get(key);
    }

    // TODO: Hash类型的相关操作

    /**
     * Hash类型操作,hash为指定hash容器,hashKey为容器内元素标识,value为元素值
     *
     * @param hash    redis中的key
     * @param hashKey redis中对应key的hash中的某个键
     * @param value   redis中对应key的hash中的某个键中对应的某个值
     */
    public <H, K, V> void pushHash(H hash, K hashKey, V value) {
        this.operateHash().put(hash, hashKey, value);
    }

    /**
     * Hash类型操作,通过Map来存如多个Hash元素,map的key即为hashKey
     *
     * @param hash redis中的key
     * @param map  存入的哈希值,含hashKey与value
     */
    public <H, K, V> void pushHashMap(H hash, Map<K, V> map) {
        this.operateHash().putAll(hash, map);
    }

    /**
     * Hash类型操作,如果不存在指定hashKey元素,则存入,返回true,否则返回false
     *
     * @param hash    redis中的key
     * @param hashKey redis中对应key的hash中的某个键
     * @param value   redis中对应key的hash中的某个键中对应的某个值
     * @return 是否存入成功
     */
    public <H, K, V> boolean pushHashIfAbsent(H hash, K hashKey, V value) {
        return this.operateHash().putIfAbsent(hash, hashKey, value);
    }

    /**
     * Hash类型操作,设置 hash 超时时间
     *
     * @param hash     redis中的key
     * @param hashKey  redis中对应key的hash中的某个键
     * @param value    redis中对应key的hash中中的某个键对应的某个值
     * @param duration 超时时间
     */
    public <H, K, V> void pushHashWithExpire(H hash, K hashKey, V value, Duration duration) {
        try {
            this.pushHash(hash, hashKey, value);
            this.expire(hash, duration);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Hash类型存在,获取指定hash的所有hashKey
     *
     * @param hash redis中的key
     * @return 返回指定hash中的所有键
     */
    public <H> Set<Object> getHashKeys(H hash) {
        return this.operateHash().keys(hash);
    }

    /**
     * Hash类型存在,指定Hash中是否存在指定 hashKey
     *
     * @param hash    redis中的key
     * @param hashKey redis中对应key的hash中的某个键
     * @return 指定hash中是否存在指定键
     */
    public <H, K> boolean hashHashKey(H hash, K hashKey) {
        return this.operateHash().hasKey(hash, hashKey);
    }


    /**
     * Hash类型操作,通过hash+hashKey获取元素
     *
     * @param hash    redis中的key
     * @param hashKey redis中对应key的hash中的某个键
     * @return redis中对应key的hash中的某个键对应的某个值
     */
    // 注意,如果存储对象中存在 LocalDateTime 类型,需要额外处理
    public <H, K> Object getHash(H hash, K hashKey) {
        return this.operateHash().get(hash, hashKey);
    }

    /**
     * Hash类型操作,获取指定hash所以元素
     *
     * @param hash 存入的hash标识
     * @return redis中对应key的hash中的键值集
     */
    // 注意,如果存储对象中存在 LocalDateTime 类型,需要额外处理
    public <H> Map<Object, Object> getHashEntries(H hash) {
        return this.operateHash().entries(hash);
    }

    // TODO: List类型操作

    /**
     * List类型操作,左入队
     *
     * @param key   list的key
     * @param value 存入的值
     * @return 入队元素个数
     */
    public <K, V> Long leftPushList(K key, V value) {
        return this.operateList().leftPush(key, value);
    }

    /**
     * List类型操作,左出队
     *
     * @param key list的key
     * @return 出队元素
     */
    public <K> Object leftPopList(K key) {
        return this.operateList().leftPop(key);
    }

    /**
     * List类型操作,右入队
     *
     * @param key   list的key
     * @param value 存入的值
     * @return 入队元素个数
     */
    public <K, V> Long rightPushList(K key, V value) {
        return this.operateList().rightPush(key, value);
    }

    /**
     * List类型操作,右入队
     *
     * @param key list的key
     * @return 出队元素
     */
    public <K> Object rightPopList(K key) {
        return this.operateList().rightPop(key);
    }

    /**
     * List类型操作,多个元素左入队
     *
     * @param key    list的key
     * @param values 存入的值
     * @return 入队元素个数
     */
    public <K, V> void leftPushListAll(K key, V... values) {
        this.operateList().leftPushAll(key, values);
    }

    /**
     * List类型操作,多个元素右入队
     *
     * @param key    list的key
     * @param values 存入的值
     * @return 入队元素个数
     */
    public <K, V> void rightPushListAll(K key, V... values) {
        this.operateList().rightPushAll(key, values);
    }

    /**
     * List类型操作,返回列表长度
     *
     * @param key list的ley
     * @return 队列元素个数
     */
    public <K> Long listSize(K key) {
        return this.operateList().size(key);
    }

    /**
     * List类型操作,获取指定索引元素,如果index为-1,则获取最后一个元素,超出索引范围则抛出数组越界异常
     *
     * @param key   list的key
     * @param index 索引左边
     * @return 指定索引元素
     */
    public <K> Object listIndex(K key, Long index) {
        return this.operateList().index(key, index);
    }

    /**
     * List类型操作,查询指定索引范围的元素
     *
     * @param key   list的key
     * @param start 索引开始
     * @param end   索引介绍
     * @return 指定索引范围元素
     */
    public <K> List<Object> listRange(K key, Long start, Long end) {
        return this.operateList().range(key, start, end);
    }

    /**
     * List类型操作,移除指定索引范围元素,返回移除个数
     *
     * @param key   list的key
     * @param value 删除的指定元素
     * @param count 删除指定元素的次数
     * @return 移除元素个数
     */
    public <K> Long listRemove(K key, Object value, Long count) {
        return this.operateList().remove(key, count, value);
    }

    // TODO: Set类型操作

    /**
     * Set类型操作,添加一个/多个元素
     *
     * @param key    set的key
     * @param values 对应key的值
     * @param <K>    key类型
     * @param <V>    values类型
     */
    public <K, V> void addSet(K key, V... values) {
        this.operateSet().add(key, values);
    }

    /**
     * Set类型操作,移除一个/多个元素
     *
     * @param key   set的key
     * @param value 移除的元素
     * @param <K>   key类型
     * @param <V>   values类型
     */
    public <K, V> void removeSet(K key, V... value) {
        this.operateSet().remove(key, value);
    }

    /**
     * Set类型操作,获取集元素个数
     *
     * @param key set的key
     * @param <K> key类型
     * @return 元素个数
     */
    public <K> Long SizeSet(K key) {
        return this.operateSet().size(key);
    }

    /**
     * Set类型操作,判断元素是否为指定set的元素
     *
     * @param key     set的key
     * @param element 元素
     * @param <K>     key的类型
     * @return 判断结果
     */
    public <K> boolean isMemberSet(K key, Object element) {
        return this.operateSet().isMember(key, element);
    }

    /**
     * Set类型操作,将set1某个元素移到set2中
     *
     * @param key1    set1的key
     * @param element set1的某个元素
     * @param key2    set2的key
     * @param <K>     key的类型
     * @return 移动结果
     */
    public <K> boolean moveSet1To2(K key1, Object element, K key2) {
        return this.operateSet().move(key1, element, key2);
    }

    /**
     * Set类型操作,获取对应集元素
     *
     * @param key set的key
     * @param <K> key的类型
     * @return 对应集元素
     */
    public <K> Set<Object> getSetMembers(K key) {
        return this.operateSet().members(key);
    }

    /**
     * Set类型操作,随机移除一个元素
     *
     * @param key set的key
     * @param <K> key的类型
     * @return 移除元素的值
     */
    public <K> Object popSet(K key) {
        return this.operateSet().pop(key);
    }

    /**
     * Set类型操作,随机移除多个元素
     *
     * @param key    set的key
     * @param number 移除元素的个数
     * @param <K>    key的类型
     * @return 移除元素的集
     */
    public <K> List<Object> popSet(K key, Long number) {
        return this.operateSet().pop(key, number);
    }

    /**
     * Set类型操作,set1、set2的并集
     *
     * @param key1 set1的key
     * @param key2 set2的key
     * @param <K>  key的类型
     * @return set1、set2的并集
     */
    public <K> Set<Object> unionSet(K key1, K key2) {
        return this.operateSet().union(key1, key2);
    }

    /**
     * Set类型操作,set1、set2的交集
     *
     * @param key1 set1的key
     * @param key2 set2的key
     * @param <K>  key的类型
     * @return set1、set2的交集
     */
    public <K> Set<Object> intersectSet(K key1, K key2) {
        return this.operateSet().intersect(key1, key2);
    }

    /**
     * Set类型操作,set与collection所含set的交集
     *
     * @param key        set的key
     * @param collection 含set的集合
     * @param <K>        key的类型
     * @return set与collection所含set的交集
     */
    public <K> Set<Object> intersectSet(K key, Collection<Object> collection) {
        return this.operateSet().intersect(key, collection);
    }

    /**
     * Set类型操作,set集的集合交集
     *
     * @param collection set集的集合
     * @return set集的集合交集
     */
    public Set<Object> intersectSet(Collection<Object> collection) {
        return this.operateSet().intersect(collection);
    }


    /**
     * Set类型操作,key1与key2的差集 set1 - set2
     *
     * @param key1 set1 的 key
     * @param key2 set2 的 key
     * @param <K>  key的类型
     * @return set1中不包含set2的集
     */
    public <K> Set<Object> differenceSet(K key1, K key2) {
        return this.operateSet().difference(key1, key2);
    }

    /**
     * Set类型操作,key对应集与collection key集对应的set集的差集 set - collection(sets)
     *
     * @param key        set的key
     * @param collection set的key集
     * @param <K>        key类型
     * @return set中不包含collection的集
     */
    public <K> Set<Object> differenceSet(K key, Collection<Object> collection) {
        return this.operateSet().difference(key, collection);
    }

    /**
     * Set类操作,collection中最后一个与全面所有set的差集
     *
     * @param collection set集 的 集合
     * @return
     */
    public Set<Object> differenceSet(Collection<Object> collection) {
        return this.operateSet().difference(collection);
    }


    // TODO:SortSet类型操作

    /**
     * SortSet类型操作,得到sortset的元素个数
     *
     * @param key sortset的key
     * @param <K> key的类型
     * @return 元素个数
     */
    public <K> Long sortSetSize(K key) {
        return this.operateSortSet().size(key);

    }

    /**
     * SortSet类型操作,得到element的排名
     *
     * @param key     sortset的key
     * @param element 元素
     * @param <K>     key的类型
     * @param <V>     元素类型
     * @return 排名
     */
    public <K, V> Long sortSetRank(K key, V element) {
        return this.operateSortSet().rank(key, element);
    }

    /**
     * SortSet操作,返回分数在score1与score2之间的元素个数
     *
     * @param key    sortset的key
     * @param score1 分数1
     * @param score2 分数2
     * @param <K>    key的类型
     * @return 该分段的元素个数
     */
    public <K> Long sortSetCount(K key, Double score1, Double score2) {
        return this.operateSortSet().count(key, score1, score2);
    }

    /**
     * SortSet操作,返回指定元素的分数
     *
     * @param key   sortset的key
     * @param value 指定元素
     * @param <K>   key的类型
     * @param <V>   元素类型
     * @return 分数
     */
    public <K, V> Double sortSetScore(K key, V element) {
        return this.operateSortSet().score(key, element);
    }

    /**
     * SortSet类型操作,存放元素并指定排序分数
     *
     * @param key   sortset的key
     * @param value 存放的元素
     * @param score 值的分数,用于排序
     * @param <K>   key的类型
     * @param <V>   value的类型
     */
    public <K, V> void addSortSet(K key, V value, Double score) {
        this.operateSortSet().add(key, value, score);
    }

    /**
     * @param key
     * @param <K>
     * @return
     */
    public <K> Long sortSetCard(K key) {
        return this.operateSortSet().zCard(key);
    }


    /**
     * SortSet操作,添加一系列元素
     *
     * @param key  sortset的key
     * @param sets 添加的元素
     * @param <K>  key的类型
     * @param <V>  value的类型
     * @return 成功添加的元素个数
     */
    public <K> Long addSortSet(K key, Set<ZSetOperations.TypedTuple<Object>> sets) {
        return this.operateSortSet().add(key, sets);
    }

    /**
     * SortSet操作,移除一个/多个元素
     *
     * @param key    sortset的key
     * @param values 移除的元素
     * @param <K>    key的类型
     * @param <V>    value的类型
     * @return 移除元素的个数
     */
    public <K, V> Long removeSortSet(K key, V... values) {
        return this.operateSortSet().remove(key, values);
    }

    /**
     * SortSet操作,移除l1与l2之间的元素
     *
     * @param key sortset的key
     * @param l1  范围1
     * @param l2  范围2
     * @param <K> key的类型
     * @return 移除范围中元素的个数
     */
    public <K> Long removeSortSetRange(K key, Long l1, Long l2) {
        return this.operateSortSet().removeRange(key, l1, l2);
    }

    /**
     * SortSet类型操作,返回分数在l1与l2之间的元素
     *
     * @param key sortset的key
     * @param l1  范围1
     * @param l2  范围2
     * @param <K> key的类型
     * @return 该范围的元素
     */
    public <K> Set<Object> sortSetRange(K key, Long l1, Long l2) {
        return this.operateSortSet().range(key, l1, l2);
    }

    /**
     * SortSet类型操作,对分段元素按分数排名并返回
     *
     * @param key    sortset的key
     * @param score1 分数1
     * @param score2 分数2
     * @param <K>    key的类型
     * @return 排序后的元素
     */
    public <K> Set<Object> sortSetRangeByScore(K key, Double score1, Double score2) {
        return this.operateSortSet().rangeByScore(key, score1, score2);
    }

    /**
     * SortSet类型操作,对分段、范围元素按分数排名并返回
     *
     * @param key    sortset的key
     * @param score1 分数1
     * @param score2 分数2
     * @param l1     范围1
     * @param l2     范围2
     * @param <K>    key的类型
     * @return 返回元素含分数
     */
    public <K> Set<Object> sortSetRangeByScore(K key, Double score1, Double score2, Long l1, Long l2) {
        return this.operateSortSet().rangeByScore(key, score1, score2, l1, l2);
    }

    /**
     * SortSet类型操作,返回分段元素包含分数
     *
     * @param <K>    key的类型
     * @param key    sortset的key
     * @param score1 分数1
     * @param score2 分数2
     * @return 排序后的元素包含分数
     */
    public <K> Set<ZSetOperations.TypedTuple<Object>> sortSetRangeByScoreWithScore(K key, Double score1, Double score2) {
        return this.operateSortSet().rangeByScoreWithScores(key, score1, score2);
    }


    /**
     * 返回指定范围、分段元素含分数
     *
     * @param key    sortset的key
     * @param score1 分数1
     * @param score2 分数2
     * @param l1     范围1
     * @param l2     范围2
     * @param <K>    key的类型
     * @return 返回的元素集,含分数
     */
    public <K> Set<ZSetOperations.TypedTuple<Object>> sortSetRangeByScoreWithScore(K key, Double score1, Double score2, Long l1, Long l2) {
        return this.operateSortSet().reverseRangeByScoreWithScores(key, score1, score2, l1, l2);
    }

    public <K, V> Set<Object> sortSetRangeByLex(K key, RedisZSetCommands.Range range) {
        return this.operateSortSet().rangeByLex(key, range);
    }

    public <K, V> Set<Object> sortSetRangeByLex(K key, RedisZSetCommands.Range range, RedisZSetCommands.Limit limit) {
        return this.operateSortSet().rangeByLex(key, range, limit);
    }

    // TODO:SortSet类型操作

    /**
     * GEO类型操作,添加一个坐标点
     *
     * @param key         geo的key
     * @param geoLocation 坐标点
     * @param <K>         key的类型
     * @return 添加成功坐标点的数量
     */
    public <K> Long addGeo(K key, RedisGeoCommands.GeoLocation geoLocation) {
        return this.operateGeo().add(key, geoLocation);
    }

    /**
     * GEO类型操作,添加单个坐标点
     *
     * @param key   geo的key
     * @param point 坐标点
     * @param m     坐标点名
     * @param <K>   key的类型
     * @param <M>   坐标名
     * @return 添加成功坐标点的数量
     */
    public <K, M> Long addGeo(K key, Point point, M m) {
        return this.operateGeo().add(key, point, m);
    }

    /**
     * GEO类型操作,添加多个坐标点
     *
     * @param key geo的key
     * @param map 存放多个坐标点,k为坐标名,v为 Point
     * @param <K> key的类型
     * @param <M> 坐标点名类型,一般为String
     * @return 添加成功坐标点的数量
     */
    public <K, M> Long addGeo(K key, Map<M, Point> map) {
        return this.operateGeo().add(key, map);
    }

    /**
     * GEO类型操作,添加多个坐标点
     *
     * @param key                 geo的key
     * @param geoLocationIterator 坐标点可迭代对象,注意,这里不是 Iterator
     * @param <K>                 key的类型
     * @return 添加成功坐标点的数量
     */
    public <K> Long addGeo(K key, Iterable<RedisGeoCommands.GeoLocation> geoLocationIterator) {
        return this.operateGeo().add(key, geoLocationIterator);
    }

    /**
     * GEO类型操作,根据坐标名移除若干个坐标点
     *
     * @param key geo的key
     * @param ms  若干的坐标名
     * @param <K> key的类型
     * @param <M> 坐标名类型
     * @return 移除坐标的数量
     */
    public <K, M> Long removeGeo(K key, M... ms) {
        return this.operateGeo().remove(key, ms);
    }

    /**
     * GEO类型操作,获取点的位置
     *
     * @param key geo的key
     * @param ms  若干坐标点
     * @param <K> key的类型
     * @param <M> 坐标点名类型
     * @return 坐标点
     */
    public <K, M> List<Point> geoPosition(K key, M... ms) {
        return this.operateGeo().position(key, ms);
    }

    /**
     * GEO类型,以字符串[s030d1h60s0]形式返回若干坐标
     *
     * @param <K> key的类型
     * @param <M> 坐标点名类型
     * @param key geo的key
     * @param ms  若干坐标名
     * @return
     */
    public <K, M> List<String> geoHash(K key, M... ms) {
        return this.operateGeo().hash(key, ms);
    }

    /**
     * GEO类型操作,获取两个坐标点的距离
     *
     * @param <K> key的类型
     * @param <M> 坐标点名类型
     * @param key geo的key
     * @param m1  坐标点1名
     * @param m2  坐标点2名
     * @return 两点距离
     * 注意:坐标点必须存在,否则抛 null
     */
    public <K, M> Distance geoDistance(K key, M m1, M m2) {
        return this.operateGeo().distance(key, m1, m2);
    }

    /**
     * GEO类型操作,获取两个坐标点的距离
     *
     * @param <K> key的类型
     * @param <M> 坐标点名类型
     * @param key geo的key
     * @param m1  坐标点1名
     * @param m2  坐标点2名
     * @return 两点距离
     */
    public <K, M> Distance geoDistance(K key, M m1, M m2, Metrics metrics) {
        return this.operateGeo().distance(key, m1, m2, metrics);
    }

    /**
     * Geo类型操作,获取一个点范围内存在的点
     *
     * @param key    geo的key
     * @param circle 范围
     * @param <K>    key的类型
     * @return 点集
     */
    public <K> GeoResults geoRadius(K key, Circle circle) {
        return this.operateGeo().radius(key, circle);
    }

    /**
     * Geo类型操作,获取一个点范围内存在的点
     *
     * @param key      geo的key
     * @param m        点名
     * @param distance 距离
     * @param <K>      key的类型
     * @param <M>      点名类型
     * @return 点集
     */
    public <K, M> GeoResults geoRadius(K key, M m, Double distance) {
        return this.operateGeo().radius(key, m, distance);
    }

    /**
     * Geo类型操作,获取一个点范围内存在的点
     *
     * @param key    geo的类型
     * @param circle 范围
     * @param args   限定参数
     * @param <K>    key的类型
     * @param <M>    点名
     * @return 点集
     */
    public <K, M> GeoResults geoRadius(K key, Circle circle, RedisGeoCommands.GeoRadiusCommandArgs args) {
        return this.operateGeo().radius(key, circle, args);
    }

    /**
     * Geo类型操作,获取一个点范围内存在的点
     *
     * @param key      geo的key
     * @param m        点名
     * @param distance 距离
     * @param args     限定参数
     * @param <K>      key的类型
     * @param <M>      点名类型
     * @return 点集
     */
    public <K, M> GeoResults geoRadius(K key, M m, Distance distance, RedisGeoCommands.GeoRadiusCommandArgs args) {
        return this.operateGeo().radius(key, m, distance, args);
    }

    // TODO: HyperLogLog类型操作

    /**
     * HyperLogLog类型操作,返回不重复元素个数
     *
     * @param key    hyperLogLog的key
     * @param values 统计的元素
     * @param <K>    key的类型
     * @param <V>    统计的元素类型
     * @return 不重复元素个数
     */
    public <K, V> Long addHyperLogLog(K key, V... values) {
        return this.operateHyperLogLog().add(key, values);
    }

    /**
     * HyperLogLog类型操作,移除统计数
     *
     * @param key HyperLogLog的key
     * @param <K> key的类型
     */
    public <K> void deleteHyperLogLog(K key) {
        this.operateHyperLogLog().delete(key);
    }

    /**
     * HyperLogLog类型操作,移除统计数
     *
     * @param key HyperLogLog的key
     * @return 返回多个统计数中不重复的元素个数
     */
    public <K> Long sizeHyperLogLog(K... key) {
        return this.operateHyperLogLog().size(key);
    }

    /**
     * HyperLogLog类型操作,融合多个统计数成为一个新统计数,并返回该统计数中不重复元素的个数(即多个统计数并集中不重复的个数)
     *
     * @param key  新统计数key
     * @param keys 若干的旧统计数
     * @param <K>  key的类型
     * @return 不重复元素个数
     */
    public <K> Long unionHyperLogLog(K key, K... keys) {
        return this.operateHyperLogLog().union(key, keys);
    }

}

RedisTest

package com.czk.common;

import com.alibaba.fastjson.JSONObject;
import com.czk.common.redis.RedisUtil;
import org.assertj.core.util.IterableUtil;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.ZSetOperations;
import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@SpringBootTest
public class CommonDemoTest {
    /**
     * 测试redis
     */

    @Resource
    RedisUtil redisUtil;

    /**
     * 测试普通String
     */
    @Test
    public void setString() {
        redisUtil.setString("setString1", "setString1");
        redisUtil.setString("setString2", 2);
        redisUtil.setString("setString3", 3.0);
    }

    /**
     * 测试定时String
     */
    @Test
    public void setStringWithExpired() {
        redisUtil.setStringWithExpired("setStringWithExpired1", "setStringWithExpired1", 1000l, null);
        redisUtil.setStringWithExpired("setStringWithExpired2", "setStringWithExpired2", 2000l, TimeUnit.SECONDS);
        redisUtil.setStringWithExpiredDuration("setStringWithExpired3", "setStringWithExpired3", Duration.ofHours(1));
    }

    /**
     * 测试定时String
     */
    @Test
    public void setStringIfAbsent() {

        boolean flag0 = redisUtil.setStringIfAbsent("setString1", "setString1");

        boolean flag1 = redisUtil.setStringWithExpiredIfAbsent("setStringWithExpired1", "setStringWithExpired1", 1000l, null);
        boolean flag2 = redisUtil.setStringWithExpiredIfAbsent("setStringWithExpired2", "setStringWithExpired2", 2000l, TimeUnit.SECONDS);
        boolean flag3 = redisUtil.setStringWithExpiredDurationIfAbsent("setStringWithExpired3", "setStringWithExpired3", Duration.ofHours(1));

        boolean flag4 = redisUtil.setStringWithExpiredIfAbsent("setStringWithExpired4", "setStringWithExpired4", 1000l, null);
        boolean flag5 = redisUtil.setStringWithExpiredIfAbsent("setStringWithExpired5", "setStringWithExpired5", 2000l, TimeUnit.SECONDS);
        boolean flag6 = redisUtil.setStringWithExpiredDurationIfAbsent("setStringWithExpired6", "setStringWithExpired6", Duration.ofHours(1));
        System.out.println(flag0);
        System.out.println(flag1);
        System.out.println(flag2);
        System.out.println(flag3);
        System.out.println(flag4);
        System.out.println(flag5);
        System.out.println(flag6);
    }

    /**
     * 测试为key设置超时时间
     */
    @Test
    public void expire() {
        boolean setStringxxx = redisUtil.expire("setStringxxx", 1000l, TimeUnit.SECONDS);
        System.out.println(setStringxxx); // 不存在的key返回false
        boolean setString1 = redisUtil.expire("setString1", 1000l, TimeUnit.SECONDS);
        boolean setString11 = redisUtil.expire("setString1", Duration.ofHours(2));
        System.out.println(setString1);
        System.out.println(setString11);
    }

    /**
     * 测试key过期的具体日期/时间
     */
    @Test
    public void expireAt() {
        redisUtil.expiredAt("setString1", new Date());
        redisUtil.expiredAt("setString1", Instant.now());
    }

    /**
     * 测试获取key的超时时间
     */
    @Test
    public void getExpire() {
        Long setStringxxx = redisUtil.getExpire("setStringxxx1");
        Long setString1 = redisUtil.getExpired("setString1", TimeUnit.SECONDS);
        System.out.println(setStringxxx);
        System.out.println(setString1);
    }

    /**
     * 测试对象转JSON存入redis
     */
    @Test
    public void setObjectToJson() {
        Student student = new Student();
        student.setName("李四");
        student.setAge(15);
        student.setLocalDateTime(LocalDateTime.now());
        student.setIdCard("123123456456789789");
        String zs = JSONObject.toJSONString(student);
        redisUtil.setString("zs", zs);
        Object zs1 = redisUtil.getString("zs");
        System.out.println(zs1); // JSON String
        JSONObject jsonObject = JSONObject.parseObject(zs1.toString()); // JSON String to JSONObject
        Student o = JSONObject.toJavaObject(jsonObject, Student.class); // JSONObject to JavaObject
        System.out.println(o);
    }

    /**
     * 测试hash存入
     */
    @Test
    public void setHash() {
        Student student1 = new Student("zs", 13, LocalDateTime.now(), "123");
        Student student2 = new Student("ls", 14, LocalDateTime.now(), "123");
        Student student3 = new Student("ww", 15, LocalDateTime.now(), "123");
        Student student4 = new Student("zl", 16, LocalDateTime.now(), "123");

        redisUtil.pushHash("students","student1",student1);
        boolean flag = redisUtil.pushHashIfAbsent("students", "student1", student1);
        System.out.println(flag);
        boolean flag1 = redisUtil.pushHashIfAbsent("students", "student1", student2);
        System.out.println(flag1);
        boolean flag2 = redisUtil.pushHashIfAbsent("students", "student2", student2);
        System.out.println(flag2);

        Map map = new HashMap();
        map.put("student3",student3);
        map.put("student4",student4);
        redisUtil.pushHashMap("students",map);
    }

    /**
     * 测试设置超时Hash
     */
    @Test
    public void setHashWithExpire(){
        Student student = new Student("zs", 13, LocalDateTime.now(), "123");
        redisUtil.pushHashWithExpire("stu","zs",student,Duration.ofHours(1));
    }

    /**
     * 测试获取Hash元素
     */
    @Test
    public void getHash(){
        User user = new User();
        user.setAge(11);
        user.setName("yy");
        user.setAddress(new Address("gz"));
        redisUtil.pushHash("users","user",user);
        Object hash = redisUtil.getHash("users", "user");
        System.out.println(hash);
    }

    /**
     * 获取hash所有原生
     */
    @Test
    public void getHashEntries(){
        Map<Object, Object> users = redisUtil.getHashEntries("users");
        System.out.println(users);
    }

    /**
     * 测试获取Hash元素,含LocalDateTime
     */
    @Test
    public void getHashWithLocalDateTime(){
        Student student = new Student("zs", 13, LocalDateTime.now(), "123");
        redisUtil.pushHash("students","zs",student);
        Object hash = redisUtil.getHash("students", "zs");
        System.out.println(hash);
    }

    /**
     * 测试redis是否存在key
     */
    @Test
    public void hasKey(){
        boolean stu = redisUtil.hasKey("stu");
        System.out.println(stu);
        boolean users = redisUtil.hasKey("users");
        System.out.println(users);
        boolean xxxxx = redisUtil.hasKey("xxxxx");
        System.out.println(xxxxx);

        boolean b = redisUtil.hashHashKey("users", "user");
        System.out.println(b);
        boolean b1 = redisUtil.hashHashKey("users", "xxxx");
        System.out.println(b1);
    }

    /**
     * 测试获取所有的HashKey
     */
    @Test
    public void getHashKeys(){
        Set students = redisUtil.getHashKeys("students");
        System.out.println(students);
    }

    /**
     * 测试删除key
     */
    @Test
    public void delKey(){
        boolean delKey = redisUtil.delKey("users");
        System.out.println(delKey);
        Long delKeys = redisUtil.delKeys(Lists.list("stu", "students"));
        System.out.println(delKeys);
    }

    /**
     * 测试list
     */
    @Test
    public void list(){
        System.out.println(redisUtil.leftPushList("list", "a"));
        redisUtil.rightPushList("list","A");
        redisUtil.leftPushListAll("list","b","c","d");
        redisUtil.rightPushListAll("list","B","C","D");
        System.out.println(redisUtil.listSize("list"));
        Collection<Object> list = redisUtil.listRange("list", 0l, 8l);
        System.out.println(list);
        System.out.println(redisUtil.listIndex("list", 0l));
        System.out.println(redisUtil.listIndex("list", redisUtil.listSize("list") - 1));
        System.out.println(redisUtil.listIndex("list", -1l));
        Long aLong = redisUtil.listRemove("list","a",1l);
        System.out.println(aLong);
        Collection<Object> objects = redisUtil.listRange("list", 0l, redisUtil.listSize("list") - 1);
        System.out.println(objects);
    }


    /**
     * 测试set
     */
    @Test
    public void set(){
        redisUtil.addSet("set1",1,3,5,"a","b","c");
        redisUtil.addSet("set2",1,2,4,6,"A","B","C","d");
        Set<Object> set1 = redisUtil.getSetMembers("set1");
        Set<Object> set2 = redisUtil.getSetMembers("set2");

        System.out.println(set1);
        System.out.println(set2);

        Set<Object> objects = redisUtil.unionSet("set1", "set2");
        System.out.println(objects);

        Set<Object> objects1 = redisUtil.differenceSet("set1", "set2");
        Set<Object> objects2 = redisUtil.differenceSet("set2", "set1");
        System.out.println(objects1);
        System.out.println(objects2);

        Collection collection = new HashSet();
        collection.add("set2");
        collection.add("set3");
        redisUtil.addSet("set3",1,2,3,4,"A","a","x","X","d","D");
        Set<Object> objects3 = redisUtil.differenceSet("set1",collection);
        System.out.println(objects3);

        collection.add("set1");
        Set set = redisUtil.differenceSet(collection);
        System.out.println(set);

        System.out.println("------------------------");

        redisUtil.addSet("s1",1,2,3,7);
        redisUtil.addSet("s2",4,5,6,1,2);
        redisUtil.addSet("s3",7,8,9,1,4,2);
        Set<Object> objects4 = redisUtil.intersectSet("s1", "s2");
        System.out.println(objects4);

        Collection collection1 = new HashSet();
        collection1.add("s2");
        Set set3 = redisUtil.intersectSet("s1", collection1);
        System.out.println(set3);
        collection1.add("s3");
        Set set4 = redisUtil.intersectSet("s1",collection1);
        System.out.println(set4);

        collection1.add("s1");
        Set set5 = redisUtil.intersectSet(collection1);
        System.out.println(set5);

        System.out.println("---------------------------------");
        System.out.println(redisUtil.popSet("s1"));
        System.out.println(redisUtil.popSet("s1"));
        Collection<Object> s2 = redisUtil.popSet("s2", 3L);
        System.out.println(s2);

        System.out.println("-----------------------------------");
        redisUtil.addSet("isMember",1);
        System.out.println(redisUtil.isMemberSet("isMember", 1));
        System.out.println(redisUtil.isMemberSet("isMember", 2));

        System.out.println("-----------------------------------");
        redisUtil.addSet("move1",1,2,3);
        redisUtil.addSet("move2",2,4,6);
        redisUtil.moveSet1To2("move1",1,"move2");
        System.out.println(redisUtil.getSetMembers("move1"));
        System.out.println(redisUtil.getSetMembers("move2"));
    }

    /**
     * 测试sortset
     */
    @Test
    public void sortSet(){
        redisUtil.addSortSet("sortSet","a",1.0);
        redisUtil.addSortSet("sortSet","b",2.0);
        Set<ZSetOperations.TypedTuple<Object>> set = new HashSet<>();
        DefaultTypedTuple typedTuple2= new DefaultTypedTuple("d",4.0);
        DefaultTypedTuple typedTuple1 = new DefaultTypedTuple("c",3.0);
        DefaultTypedTuple typedTuple4 = new DefaultTypedTuple("f",6.0);
        DefaultTypedTuple typedTuple3 = new DefaultTypedTuple("e",5.0);
        DefaultTypedTuple typedTuple6 = new DefaultTypedTuple("h",8.0);
        DefaultTypedTuple typedTuple7 = new DefaultTypedTuple("i",9.0);
        DefaultTypedTuple typedTuple5 = new DefaultTypedTuple("g",7.0);
        set.add(typedTuple1);
        set.add(typedTuple2);
        set.add(typedTuple3);
        set.add(typedTuple4);
        set.add(typedTuple5);
        set.add(typedTuple6);
        set.add(typedTuple7);
        System.out.println("add:"+redisUtil.addSortSet("sortSet", set));
        System.out.println("count:"+redisUtil.sortSetCount("sortSet", 1.1, 8.0));
        System.out.println("size:"+redisUtil.sortSetSize("sortSet"));
        System.out.println(redisUtil.sortSetRank("sortSet", "a")); // 1
        System.out.println(redisUtil.sortSetScore("sortSet","b")); // 2.0
        System.out.println(redisUtil.sortSetCard("sortSet"));
        Set<Object> sortSet = redisUtil.sortSetRange("sortSet", 0l, 5l); // 0~5索引元素
        System.out.println(sortSet);
        Set<Object> sortSet1 = redisUtil.sortSetRangeByScore("sortSet", 1.0, 5.0); // 1.0~5.0分数元素
        System.out.println(sortSet1);
        Set<ZSetOperations.TypedTuple<Object>> sortSet2 = redisUtil.sortSetRangeByScoreWithScore("sortSet", 1.0, 5.5);
        sortSet2.stream().forEach(e->{
            System.out.println(e.getValue() + "--" + e.getScore());
        });
        System.out.println("------------------");
        Set<ZSetOperations.TypedTuple<Object>> sortSet3 = redisUtil.sortSetRangeByScoreWithScore("sortSet", 1.0, 5.5,0l,3l);
        sortSet3.stream().forEach(e->{
            System.out.println(e.getValue() + "--" + e.getScore());
        });
        System.out.println("------------------");
        redisUtil.removeSortSet("sortSet","a");
        redisUtil.removeSortSetRange("sortSet",1l,4l);
        Set<ZSetOperations.TypedTuple<Object>> sortSet4 = redisUtil.sortSetRangeByScoreWithScore("sortSet", 1.0, 5.5,0l,3l);
        sortSet4.stream().forEach(e->{
            System.out.println(e.getValue() + "--" + e.getScore());
        });
    }

    /**
     * 测试geo
     */
    @Test
    public void geo(){
        RedisGeoCommands.GeoLocation<String> gz = new RedisGeoCommands.GeoLocation<>("广州", new Point(1.0, 1.0));
        Long geo = redisUtil.addGeo("geo", gz);
        System.out.println(geo);


        Map map = new HashMap();
        map.put("深圳",new Point(2.0, 2.0));
        map.put("汕头",new Point(2.5, 2.5));
        Long geo1 = redisUtil.addGeo("geo", map);
        System.out.println(geo1);

        Long aLong = redisUtil.addGeo("geo", new Point(1.5, 1.5), "佛山");
        System.out.println(aLong);
        Iterable<RedisGeoCommands.GeoLocation> iterable = IterableUtil.iterable(new RedisGeoCommands.GeoLocation<>("上海", new Point(3.0, 3.0)),
                                                                                new RedisGeoCommands.GeoLocation<>("北京", new Point(4.0, 4.0)));
        redisUtil.addGeo("geo",iterable);

        Map map1 = new HashMap();
        map1.put("remove1",new Point(2.1, 2.1));
        map1.put("remove2",new Point(2.2, 2.2));
        map1.put("exist",new Point(2.3, 2.3));
        Long geo2 = redisUtil.addGeo("geo", map1);
        System.out.println(geo2);
        Long aLong1 = redisUtil.removeGeo("geo", "remove1", "remove2");
        System.out.println(aLong1);

        Distance distance = redisUtil.geoDistance("geo", "广州", "深圳");
        System.out.println(distance);
        System.out.println(distance.getValue() +"-" +distance.getMetric());
        Distance distance1 = redisUtil.geoDistance("geo", "广州", "深圳", Metrics.MILES);
        System.out.println(distance1);
        Distance distance2 = redisUtil.geoDistance("geo", "广州", "深圳", Metrics.KILOMETERS);
        System.out.println(distance2);

        Collection<Point> points = redisUtil.geoPosition("geo", "汕头", "广州");
        System.out.println(points);

        Collection<String> list = redisUtil.geoHash("geo", "深圳", "佛山");
        System.out.println(list);

        Circle circle = new Circle(new Point(1.0,1.0),10000.0);

        GeoResults geo3 = redisUtil.geoRadius("geo", circle);
        System.out.println(geo3);
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        GeoResults geo4 = redisUtil.geoRadius("geo", circle, geoRadiusCommandArgs);
        System.out.println(geo4);
        Distance distance3 = new Distance(500,Metrics.MILES);
        GeoResults geoResults = redisUtil.geoRadius("geo", "深圳", distance3, geoRadiusCommandArgs.limit(3));
        System.out.println(geoResults);

    }

    @Test
    void operateHyperLogLog(){

        Long loglog1 = redisUtil.operateHyperLogLog().add("LOGLOG1", 1,2,3,4,5,6,7,1,2,3,4,5,6,7,8,9,0);
        Long loglog2 = redisUtil.operateHyperLogLog().add("LOGLOG2", 1,2,3,4,5,6,7,8,9,0,11);
        System.out.println(loglog1);
        System.out.println(loglog2);
        Long size = redisUtil.operateHyperLogLog().size("LOGLOG1", "LOGLOG2");
        System.out.println(size);
        //        redisUtil.operateHyperLogLog().delete("LOGLOG1");
        Long union = redisUtil.operateHyperLogLog().union("LOGLOG3", "LOGLOG1", "LOGLOG2");
        System.out.println(union);

        System.out.println("----------------------");
        redisUtil.addHyperLogLog("LOG1",1,2,3);
        redisUtil.addHyperLogLog("LOG1",4,5,6);
        redisUtil.addHyperLogLog("LOG2",1,2,3,7);
        System.out.println(redisUtil.sizeHyperLogLog("LOG1"));
        System.out.println(redisUtil.sizeHyperLogLog("LOG2"));
        System.out.println(redisUtil.sizeHyperLogLog("LOG1", "LOG2"));
        System.out.println(redisUtil.unionHyperLogLog("LOG3", "LOG1", "LOG2"));
        redisUtil.deleteHyperLogLog("LOG1");
    }

    @Test
    public void t(){
        redisUtil.setString("1","user1");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值