SpringBoot使用RedisTemplate、StringRedisTemplate操作Redis

news2024/11/13 16:15:06

前言

RedisTemplate 是 Spring Boot 访问 Redis 的核心组件,底层通过 RedisConnectionFactory 对多种 Redis 驱动进行集成,上层通过 XXXOperations 提供丰富的 API ,并结合 Spring4 基于泛型的 bean 注入,极大的提供了便利,成为日常开发的一大利器。

本文介绍如何在 SpringBoot 中集成Redis,并介绍 RedisTemplate 对象操作的常用方法。

RedisTemplateStringRedisTemplate的区别:

1.  两者的关系是 StringRedisTemplate 继承 RedisTemplate。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.data.redis.core;

import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializer;

public class StringRedisTemplate extends RedisTemplate<String, String> {
    public StringRedisTemplate() {
        this.setKeySerializer(RedisSerializer.string());
        this.setValueSerializer(RedisSerializer.string());
        this.setHashKeySerializer(RedisSerializer.string());
        this.setHashValueSerializer(RedisSerializer.string());
    }

    public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
        this();
        this.setConnectionFactory(connectionFactory);
        this.afterPropertiesSet();
    }

    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
        return new DefaultStringRedisConnection(connection);
    }
}

2. 两者的数据是不共通的,也就是说 StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate 中的数据。

3. SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。

StringRedisTemplate 默认采用的是 String 的序列化策略,保存的 key 和 value 都是采用此策略序列化保存的。

RedisTemplate 默认采用的是JDK的序列化策略,保存的 key 和 value 都是采用此策略序列化保存的。

RedisTemplate默认使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入Redis数据库,这个时候打开Redis查看的时候,你会看到你的数据不是以可读的形式展现的,而是以字节数组显示。

那么就可以得出一个结论,如果你想使用默认的配置来操作redis,则如果操作的数据是字节数组,就是用RedisTemplate,如果操作的数据是明文,使用StringRedisTemplate。

当然在项目中真实使用时,一般是自定义RedisTemplate的Bean实例,来设置具体的序列化策略,说白了就是RedisTemplate通过自定义Bean可以实现和StringRedisTemplate一样的序列化,使用起来更加灵活。

一、Redis五种基础数据结构

首先对redis来说,所有的key(键)都是字符串。我们在谈基础数据结构时,讨论的是存储值的数据类型,主要包括常见的5种数据类型,分别是:String、List、Set、Zset、Hash。

结构类型结构存储的值结构的读写能力
String字符串可以是字符串、整数或浮点数对整个字符串或字符串的一部分进行操作;对整数或浮点数进行自增或自减操作
List列表一个链表,链表上的每个节点都包含一个字符串对链表的两端进行push和pop操作,读取单个或多个元素;根据值查找或删除元素
Set集合包含字符串的无序集合字符串的集合,包含基础的方法有看是否存在添加、获取、删除;还包含计算交集、并集、差集等
Hash散列包含键值对的无序散列表包含方法有添加、获取、删除单个元素
Zset有序集合和散列一样,用于存储键值对字符串成员与浮点数分数之间的有序映射;元素的排列顺序由分数的大小决定;包含方法有添加、获取、删除单个元素以及根据分值范围或成员来获取元素

        
        
   

二、RedisTemplate 概述

1、Redis 是一个缓存、消息代理和功能丰富的键值存储。Spring Boot 为 Lettuce 和 Jedis 客户端库提供基本的自动配置,并为 Spring Data Redis 提供抽象。官网传送。

2、spring-boot-starter-data-redis 启动器,整合了需要的依赖项,默认情况下,它使用 Lettuce 作为客户端。这个启动器同时处理传统应用程序和反应性应用程序(reactive applications)。

3、官方还提供了一个 spring-boot-starter-data-redis-reactive 启动器,用于与具有 reactive 支持的其他存储保持一致。

4、可以像注入任何其他 Spring Bean 一样注入一个自动配置的 RedisConnectionFactory、StringRedisTemplate 或普通的 RedisTemplate 实例。class StringRedisTemplate extends RedisTemplate<String, String>

5、默认情况下,Redis 实例尝试连接本地主机(localhost)端口为 6379 的 Redis 服务器,默认使用空密码,连接 0 号数据库:RedisProperties

6、可以实现 LettuceClientConfigurationBuilderCustomizer 接口,以实现更高级的定制。如果使用的是 Jedis 客户端,则实现 JedisClientConfigurationBuilderCustomizer 接口。

三、SpringBoot通过RedisTemplate连接Redis

一、引入依赖

<!-- redis 缓存操作 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- pool 对象池 -->
<!-- 使用lettuce客户端需要引入commons-pool2依赖 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

二、基础配置

1、配置application.yml文件

配置如下:

spring:
  data:
    redis:
      mode: master
      # 地址
      host: 30.46.34.190
      # 端口,默认为6379
      port: 6379
      # 密码,没有不填
      password: ''
      # 几号库
      database: 1
      sentinel:
        master: master
        nodes: 30.46.34.190
      cluster:
        nodes: 30.46.34.190
      lettuce:
        pool:
          # 连接池的最大数据库连接数
          max-active: 200
          # 连接池最大阻塞等待时间(使用负值表示没有限制)
          max-wait: -1ms
          # 连接池中的最大空闲连接
          max-idle: 50
          # 连接池中的最小空闲连接
          min-idle: 8
     

2、RedisTemplate配置

代码如下:

/*
*自定义Redis配置类,进行序列化以及RedisTemplate设置
*/
@Configuration
@EnableConfigurationProperties({RedisProperties.class})
public class RedisConfig {

    @Value("${spring.data.redis.mode}")
    private String redisMode;

    private final RedisProperties properties;

    public RedisConfig(RedisProperties properties) {
        this.properties = properties;
    }

    @Bean
    public LettuceConnectionFactory redisConnectionFactory(
            ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
            ClientResources clientResources) {
        GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(this.properties.getLettuce().getPool().getMaxActive());
        config.setMaxIdle(this.properties.getLettuce().getPool().getMaxIdle());
        config.setMinIdle(this.properties.getLettuce().getPool().getMinIdle());
        config.setMaxWait(this.properties.getLettuce().getPool().getMaxWait());

        LettucePoolingClientConfiguration clientConfiguration = LettucePoolingClientConfiguration
                .builder()
                .poolConfig(config)
                .build();

        switch (redisMode) {
            case "master":
                RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
                redisStandaloneConfiguration.setDatabase(this.properties.getDatabase());
                redisStandaloneConfiguration.setPassword(this.properties.getPassword());
                redisStandaloneConfiguration.setHostName(this.properties.getHost());
                redisStandaloneConfiguration.setPort(this.properties.getPort());
                return new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfiguration);
            case "sentinel":
                RedisSentinelConfiguration redisSentinelConfig = new RedisSentinelConfiguration();
                redisSentinelConfig.setDatabase(this.properties.getDatabase());
                redisSentinelConfig.setPassword(this.properties.getPassword());
                redisSentinelConfig.setMaster(this.properties.getSentinel().getMaster());
                redisSentinelConfig.setSentinels(
                        this.properties.getSentinel().getNodes().stream()
                                .map(RedisNode::fromString).collect(Collectors.toList())
                );
                return new LettuceConnectionFactory(redisSentinelConfig, clientConfiguration);
            case "cluster":
                RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
                redisClusterConfiguration.setPassword(this.properties.getPassword());
                redisClusterConfiguration.setClusterNodes(
                        this.properties.getCluster().getNodes().stream()
                                .map(RedisNode::fromString).collect(Collectors.toList())
                );
                return new LettuceConnectionFactory(redisClusterConfiguration, clientConfiguration);

            default:
                throw new IllegalArgumentException("无效的redis mode配置");
        }
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){

        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer<>(om, Object.class);

        
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置数据源的连接工厂(默认会传入框架中自带的,也就是读取配置文件装配的LettuceConnectionFactory)        
        template.setConnectionFactory(connectionFactory);
        // 使用StringRedisSerializer序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        // 设置值(value)的序列化采用Jackson2JsonRedisSerializer
        template.setValueSerializer(serializer);
        // 使用StringRedisSerializer序列化和反序列化redis hash类型的key值
        template.setHashKeySerializer(new StringRedisSerializer());
        // 序列化和反序列化redis hash类型的value值
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
    
}

3. 编写测试类

package com.zpli.web.test;

/**
 * created at 2024/7/9 19:08
 *
 * @author somnuszpli
 */

import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {

    @Autowired
    private RedisTemplate redisTemplate;// <1>

    @Test
    public void test() throws Exception {

        redisTemplate.opsForValue().set("student:1", "zpli"); // <2>

        Assertions.assertThat(redisTemplate.opsForValue().get("student:1"))
                .isEqualTo("kirito");
    }
}

<1> 引入了 RedisTemplate,这个类是 spring-starter-data-redis 提供给应用直接访问 redis 的入口。从其命名就可以看出,其是模板模式在 spring 中的体现,与 restTemplate,jdbcTemplate 类似,而 springboot 为我们做了自动的配置,具体已在上文详解。

<2> redisTemplate 通常不直接操作键值,而是通过 opsForXxx() 访问,在本例中,key 和 value 均为字符串类型。绑定字符串在实际开发中也是最为常用的操作类型。

四、详解 RedisTemplate 的 API


RedisTemplate 为我们操作 Redis 提供了丰富的 API,可以将他们简单进行下归类。

1.常用数据操作

方法描述
Boolean hasKey(K key)key 是否存在
Long countExistingKeys(Collection<K> keys)redis 中存在 keys 的数量
Boolean delete(K key)删除 key
Long delete(Collection<K> keys)批量删除 keys
DataType type(K key)获取 key 的类型
void rename(K oldKey, K newKey)重命名 key
Boolean renameIfAbsent(K oldKey, K newKey)如果存在,重命名 key
Boolean expire(K key, long timeout, TimeUnit unit)为 key 设置过期时间
Boolean expireAt(K key, Date date)为 key 设置过期时间
Long getExpire(K key)获取 key 的过期时间
Long getExpire(K key, TimeUnit timeUnit)获取 key 的过期时间
Boolean persist(K key)移除 key 的过期时间,使其变为永久
Boolean move(K key, int dbIndex)将 key 移动到 dbIndex 中

若以 bound 开头,则意味着在操作之初就会绑定一个 key,后续的所有操作便默认认为是对该 key 的操作,算是一个小优化。

API返回值类型说明
redisTemplate.opsForValue()      ValueOperations操作 String 类型 数据
redisTemplate.opsForHash()HashOperations操作 Hash 类型数据
redisTemplate.opsForList() ListOperations操作 List 类型数据
redisTemplate.opsForSet() SetOperations操作 Set 类型数据
redisTemplate.opsForZSet()ZSetOperations操作 SortedSet 类型数据
redisTemplate.boundValueOps(K key)BoundValueOperations操作 String 类型 数据
redisTemplate.boundHashOps(K key)BoundHashOperations操作 Hash 类型数据
redisTemplate.boundListOps(K key)BoundListOperations操作 List 类型数据
redisTemplate.boundSetOps(K key)BoundSetOperations操作 Set 类型数据
redisTemplate.boundZSetOps(K key)BoundZSetOperations操作 SortedSet 类型数据

        

        
      

        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("name", "zpli");

        Object age = valueOperations.get("name");

        BoundValueOperations<String, String> boundValueOperations = stringRedisTemplate.boundValueOps("name");
        String nameByBound = boundValueOperations.get();

2. 几种数据结构操作的具体用法

String 类型

org.springframework.data.redis.core.ValueOperations 处理 String 类型数据。

【ValueOperations源码】

调用ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();得到ValueOperations。然后可通过valueOperations调用相应方法。当然也可以直接通过stringRedisTemplate.opsForValue()进行操作。

package com.zpli.web;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * created at 2024/7/10 15:23
 * 注入 RedisTemplate 或者 StringRedisTemplate 其中一个即可,前者是后者的父类,它们都已经默认在 Spring 容器中
 *
 * @author somnuszpli
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void test1() {
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("age", 24);
        Object age = valueOperations.get("age");
        System.out.println(age);

        stringRedisTemplate.opsForValue().set("name", "zpli");
        String name = stringRedisTemplate.opsForValue().get("name");
        System.out.println(name);

    }
}
方法 描述
set(K key, V value) 

存储到 redis。key 已经存在时,覆盖旧值,不存在时新增。

key、value 不能为 null

set(K key, V value, long timeout, TimeUnit unit) 

设置失效时间为指定时间。超过后 key 会被移除

set(K key, V value, Duration timeout)

设置超时时间,Duration 是 Jdk 8 的 API。

超过指定时间后,key 被移除

set(K key, V value, long offset)

覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始

get(Object key)

获取指定 key 的 value,key 不存在时,返回 null。key 不能 null

getAndSet(K key, V value)

获取 key 的旧值,并赋值新的 value。key 不能 null

get(K key, long start, long end)

获取指定 key 指定范围的字符串 [start,end],从索引 0 开始。

key 不能 null

append(K key, String value)

将新的 value 追加到 key 的旧值尾部,key 不存在时,自动新建。key 不能为 null

Long size(K key)

获取 key 的 value 的长度,key 不存在时,返回 0。key 不能为 null

Boolean setIfAbsent(K key, V value)

如果 key 不存在,则新增,否则不改变原来的值。其余重载方法与 set 方法对应。key、value 不能为 null

Boolean setIfAbsent(K key, V value, long timeout, TimeUnit unit)

Boolean setIfAbsent(K key, V value, Duration timeout)

1、key 不存在时进行设值,返回 true; 否则 key 存在时,不进行设值,返回 false.

2、此方法相当于先设置 key,然后设置 key 的过期时间,它的操作是原子性的,是事务安全的。

3、相当于:SET anyLock unique_value NX PX 30000,NX是指如果key不存在就成功,key存在返回false,PX可以指定过期时间

Boolean setIfPresent(K key, V value, Duration timeout)

key 存在时,才修改它的值,否则不新增,与 setIfAbsent 相反

Long increment(K key)

将存储为字符串值的整数值增加1,并返回结果。

key 不存在时自动新增

Long increment(K key, long delta)

将存储为字符串值的整数值增加 delta,并返回结果。

key 不存在时自动新增。delta 为负数时,做减法

Double increment(K key, double delta)

将存储为字符串值的小数值增加 delta,并返回结果。

key 不存在时自动新增

Long decrement(K key)

将存储为字符串的整数值减1,key 不存在时自动创建

Long decrement(K key, long delta)

减去指定的数值,key 不存在时自动创建。delta为负数时,做加法

List multiGet(Collection keys)

同时获取多个 key 的值,按请求的 key 的顺序返回对应的 value,key 不存在的返回 null

multiSet(Map<? extends K, ? extends V> map)

同时存储多个 key-value

Boolean multiSetIfAbsent(Map<? extends K, ? extends V> map)

当 key 不存在时新增,否则不进行操作

   


   
   

List 类型

org.springframework.data.redis.core.ListOperations 处理 List 类型数据。

【ListOperations源码】

方法

描述

Long size(K key)

返回存储在键中的列表的长度。键不存在时,返回 0;key 存储的值不是列表时返回错误。

Long leftPush(K key, V value)

将指定的值插入到列表的头部。键不存在自动创建。(从左边插入)。返回 list 的大小(size)。

Long leftPushAll(K key, V... values)

批量从左插入。key 不能为 null。返回 list 的大小(size)。

Long leftPushAll(K key, Collection values)

批量从左插入。key,values 不能为 null。

Long leftPush(K key, V pivot, V value)

对于名字为 key 的 list,从左往右先查询第一个出现的 pivot 元素,然后将 value 插入到它的左边。

Long leftPushIfPresent(K key, V value)

只有当 key 存在时,才新增,否则不处理。

Long rightPush(K key, V value)

右侧插入,key 不存在时,自动创建。

Long rightPush(K key, V pivot, V value)

从左往右查找第一个 pivot 元素,然后将新的 value 插入到它的右侧。

Long rightPushAll(K key, Collection values)

右侧批量插入

Long rightPushAll(K key, V... values)

右侧批量插入

Long rightPushIfPresent(K key, V value)

当 key 存在时,进行右侧插入,否则不处理。

set(K key, long index, V value)

为名字为 key 的列表索引为 index 的元素替换为新的 value 值。key 必须存在,index 索引不能越界

Long remove(K key, long count, Object value)

删除列表(key) 中指定个数(count)的元素(value)。count=0:删除所有 value;count>0:从左往右删除 count 个 value;count<0,从右往左删除。

List range(K key, long start, long end)

查询 list 的元素值,索引范围为 [start,end],-1 表示倒数第一个元素

V index(K key, long index)

获取列表中指定索引处的元素。index 越界时,返回 null;key 不存在时,返回 null。索引 index=-1 表示倒数第一个元素。

V leftPop(K key)

弹出最左边的元素,弹出之后该值在列表中将不复存在。当列表为空时,返回 null。

V rightPop(K key)

弹出最右边的元素,弹出之后该值在列表中将不复存在。当列表为空时,返回 null。

V leftPop(K key, long timeout, TimeUnit unit)

弹出最左边的元素,当元素不存在时,线程阻塞等待,直到存在新元素,或者超时抛出异常

V rightPop(K key, long timeout, TimeUnit unit)

弹出最右边的元素,当元素不存在时,线程阻塞等待,直到存在新元素,或者超时抛出异常

Hash 类型

org.springframework.data.redis.core.HashOperations 处理 Hash 类型数据。

HashOperations源码】​

方法

描述

Long size(H key)

获取指定 hash(key) 的元素个数,kye 不存在时,返回 0

Boolean hasKey(H key, Object hashKey)

判断 hash 中 是否存在指定的元素,key 不存在时,返回 false

Set keys(H key)

获取指定 hash(key) 中所有的 hashKey。key 不存在时,返回空集合[]

List values(H key)

获取指定 hash(key) 的所有值。key 不存在时,返回空 list

Long delete(H key, Object... hashKeys)

删除指定的 hash(key) 中指定的元素(hansKeys),返回成功删除元素个数,key 不存在时返回 0

void put(H key, HK hashKey, HV value)

往 key 中插入键值对 hashKey-value。hashKey 重复时,后插入的覆盖旧值。key 不存在时,自动新增

void putAll(H key, Map<? extends HK, ? extends HV> m)

单次插入多个元素。key 不存在时自动新增

Boolean putIfAbsent(H key, HK hashKey, HV value)

key 或者 hashKey 不存在时,才插入值

HV get(H key, Object hashKey)

获取 hash 中指定的 hashKey,key 不存在时,返回 null

Map<HK, HV> entries(H key)

获取指定 key 的 hash map。key 不存在时,返回空 map

Long lengthOfValue(H key, HK hashKey)

获取 key 对应的 hash map 的 hashKey 对应的元素值的长度

List multiGet(H key, Collection hashKeys)

同时获取 key 对应的 hash map 中的多个元素值,hashKey 不存在时,返回 null

Long increment(H key, HK hashKey, long delta)

为指定 key 的 hash map 中的元素 hashKey 的数值加上整数值 delta。key 不存在时,直接新增

Double increment(H key, HK hashKey, double delta)

为指定 key 的 hash map 中的元素 hashKey 的数值加上浮点数值 delta。key 不存在时,直接新增


 

Set 类型

org.springframework.data.redis.core.SetOperations 处理无序集合(Set) 类型数据。

【SetOperations源码】

方法

描述

Long add(K key, V... values)

往 set 中添加元素,key 不存在时,自动新建。value 重复时,覆盖旧值。返回 set 中的元素个数。

Long remove(K key, Object... values)

移除 set 中的元素。返回 set 中剩余的元素个数。set 中没有元素时,自动删除 key。key 不存在时不影响。

Boolean move(K key, V value, K destKey)

将 key 对应的 set 中的值 value 剪切到目标 set(destKey) 中。key、value、destKey 不存在时,不做任何操作.

V pop(K key)

随机弹出 set 中的一个元素,弹出后,set 中就没有了。当 set 为空时,返回 null。

List pop(K key, long count)

随机弹出 set 中 count 个元素,如果 set 的大小为 3,而 count 为 5,此时只会返回 3 个元素。

Long size(K key)

获取 key 对应 set 的集合大小. key 不存在时,返回 0

Set members(K key)

获取 set 中所有的元素,key 不存在时,返回空 set。

V randomMember(K key)

从 set 中随机返回一个元素,set 中此元素还会存在。key 不存在时,返回 null。

List randomMembers(K key, long count)

随机返回 set 中 count 个元素。

Boolean isMember(K key, Object o)

判断 key 对应的 set 中是否包含元素 o。key 不存在时,返回 false。

Set union(K key, K otherKey)

获取 key 与 otherKey 对应的 set 的并集。旧值不受影响,返回合并后的值。

Set union(K key, Collection otherKeys)

获取多个 set 的并集

Long unionAndStore(K key, K otherKey, K destKey)

求 key 、otherKey 的 set 并集,并将结果添加到 destKey 中。destKey 不存在时,自动创建。返回新集合中的元素个数。当 destKey 中事先已经有值,则会被先清除。

Long unionAndStore(K key, Collection otherKeys, K destKey)

将多个 set 的并集结果放入到 destKey 对应的 set 中,destKey 不存在时,自动创建。当 destKey 中事先已经有值,则会被先清除。

Set difference(K key, K otherKey)

求 key 与 otherKey 对应的 set 的差集,key 减去 otherKey 后剩余的结果。

Set difference(K key, Collection otherKeys)

获取 key 与所有 otherKeys 的差集。

Long differenceAndStore(K key, K otherKey, K destKey)

将差集结果放入到 destKey 中。当 destKey 中事先已经有值,则会被先清除。

Long differenceAndStore(K key, Collection otherKeys, K destKey)

将差集结果放入到 destKey 中。当 destKey 中事先已经有值,则会被先清除。

Set intersect(K key, K otherKey)

获取 key 与 otherKey 的交集,双方都拥有的元素

Set intersect(K key, Collection otherKeys)

获取 key 与其它所有 otherKeys 的交集

Long intersectAndStore(K key, K otherKey, K destKey)

将交集结果放到 destKey 集合中。当 destKey 中事先已经有值,则会被先清除。

Long intersectAndStore(K key, Collection otherKeys, K destKey)将交集结果放到 destKey 集合中。当 destKey 中事先已经有值,则会被先清除。


zset 类型

org.springframework.data.redis.core.ZSetOperations 处理有序集合(Set) 的数据。

【ZSetOperations源码】

方法

描述

Boolean add(K key, V value, double score)

为有序集合添加元素. 如果 value 已经存在,则更新. score 表示权重,用于排序,值越小,排序越靠前(由小到大)。key 不存在时,直接新增。成功插入时返回 true,失败时返回 false。

Long rank(K key, Object o)

获取元素 o 在有序集合中的索引

Set range(K key, long start, long end)

获取有序的集合中指定索引范围的值,索引从0开始,-1 表示倒数第一个元素。

Set rangeByScore(K key, double min, double max)

根据权重范围查询

Set rangeByScore(K key, double min, double max, long offset, long count)

offset 表示偏移量,count 表示需要获取的个数

Long count(K key, double min, double max)

获取权重在 [min,max] 直接的元素个数

Long remove(K key, Object... values)

删除有序集合中指定的元素(value)

Long removeRange(K key, long start, long end)

删除有序集合中指定索引范围内的元素

Long removeRangeByScore(K key, double min, double max)

删除有序集合中指定权重范围内的元素

Long zCard(K key)

获取集合的大小

Long size(K key)

获取集合的大小,底层调用 zCard

Double score(K key, Object o)

获取集合中指定元素的权重

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1916244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

D-DPCC: Deep Dynamic Point Cloud Compression via 3D Motion Prediction

1. 论文基本信息 发布于&#xff1a; 2022 2. 创新点 首先提出了一种端到端深度动态点云压缩框架(D-DPCC)&#xff0c;用于运动估计、运动补偿、运动压缩和残差压缩的联合优化。提出了一种新的多尺度运动融合(MMF)模块用于点云帧间预测&#xff0c;该模块提取和融合不同运动流…

网络安全----防御----防火墙安全策略组网

防火墙组网 要求&#xff1a; 1&#xff0c;DMz区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问。 2&#xff0c;生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3&#xff0c;办公区设备10.0.…

3d模型选不中任何东西是什么原因?---模大狮模型网

在进行3D模型设计过程中&#xff0c;有时会遇到无法选择模型中的任何元素的问题。这种情况可能会影响设计师的工作效率和体验&#xff0c;因此了解问题的原因以及如何解决是至关重要的。本文将探讨在3D建模中遇到无法选中模型元素的原因及解决方法。 一、问题原因分析 无法选中…

1.9-改进的CBOW模型的实现

文章目录 0引言1 CBOW模型的重构1.1模型初始化1.2模型的前向计算1.3模型的反向传播 2总结 0引言 前面讲述了对word2vec高速化的改进&#xff1a; 改进输入侧的计算&#xff0c;变成Embedding&#xff0c;即从权重矩阵中选取特定的行&#xff1b;改进输出侧的计算&#xff0c;包…

最新的数据防泄密方案来袭!

沙箱技术作为一种先进的数据安全解决方案&#xff0c;在数据防泄密领域发挥着日益重要的作用。它通过构建一个隔离的虚拟环境&#xff0c;使得应用程序在该环境中运行&#xff0c;从而隔离了应用程序对系统资源的直接访问&#xff0c;有效防止了数据泄露的风险。 一、沙箱技术在…

[C++] 轻熟类和对象

类的定义 格式规范 class为定义类的关键字&#xff0c;后有类名&#xff0c;类的主体存于{}中&#xff1b;类定义结束时后面的分号不能省略&#xff1b;类体的内容成为类的成员&#xff0c;类中的变量成为成员变量&#xff0c;函数成为方法或成员函数&#xff1b;C兼容C语言的…

[spring] Spring MVC - security(上)

[spring] Spring MVC - security&#xff08;上&#xff09; 这部分的内容基本上和 [spring] rest api security 是重合的&#xff0c;主要就是添加 验证&#xff08;authentication&#xff09;和授权&#xff08;authorization&#xff09;这两个功能 即&#xff1a; 用户…

SpringBoot的老年慢性病药物管理系统-计算机毕业设计源码70568

目录 摘要 Abstract 第一章 绪论 1.1 选题背景及意义 1.2 国内外研究现状 1.3 研究方法 第二章 相关技术介绍 2.1 MySQL简介 2.2 Java编程语言 2.3 B/S模式 2.4 springboot框架 第三章 老年慢性病药物管理系统 系统分析 3.1 系统目标 3.2 系统可行性分析 3.2.1 技…

STM32中断学习记录

文章目录 NVICNVIC是什么NVIC寄存器NVIC 结构体NVIC 相关固件库函数 如何定义优先级中断编程外部中断 EXTIEXIT 外部中断/事件控制器EXIT的使用EXTI内部寄存器分析GPIO触发中断例程为什么中断后要清除中断标志位 SysTick的使用SysTick分析 NVIC NVIC是什么 待补充.........NVI…

ChatTTS的爆火是必然,它正在重新定义我们与机器对话的方式

当AI技术与语音合成相遇&#xff0c;开源技术众多&#xff0c;为什么 ChatTTS 能够一夜爆火&#xff1f;你有听说过能说情感真切文字的 AI 吗&#xff1f; 前言 想象一下&#xff0c;你只需输入一句话&#xff0c;AI就能念得声情并茂&#xff0c;不仅支持中英文混读&#xff0…

自注意力简介

在注意力机制中&#xff0c;每个查询都会关注所有的键值对并生成一个注意力输出。如果查询q&#xff0c;键k和值v都来自于同一组输入&#xff0c;那么这个注意力就被称为是自注意力&#xff08;self-attention&#xff09;。自注意力这部分理论&#xff0c;我觉得台大李宏毅老师…

一位互联网公司项目经理繁忙的一天

早晨&#xff1a;准备与计划 7:00 AM - 起床与准备 项目经理起床后&#xff0c;快速洗漱并享用早餐。之后花几分钟查看手机上的邮件和消息&#xff0c;确保没有紧急事务需要立即处理。 7:30 AM - 通勤时间 前往公司。在通勤途中&#xff0c;通过手机或平板电脑查看当天的会议…

硅谷甄选运营平台-vue3组件通信方式

vue3组件通信方式 vue2组件通信方式&#xff1a; props:可以实现父子组件、子父组件、甚至兄弟组件通信自定义事件:可以实现子父组件通信全局事件总线$bus:可以实现任意组件通信pubsub:发布订阅模式实现任意组件通信vuex:集中式状态管理容器&#xff0c;实现任意组件通信ref:父…

简单了解下安全测试!

一、基本概念 安全测试是在软件产品开发基本完成时&#xff0c;验证产品是否符合安全需求定义和产品质量标准的过程。它主要检查系统对非法侵入渗透的防范能力&#xff0c;旨在通过全面的脆弱性安全测试&#xff0c;发现系统未知的安全隐患并提出相关建议&#xff0c;确保系统…

星申刹车盘平衡机:精准与高效兼备

星申动双工位刹车盘动平衡机是一款具备测量和切削两个工位的高精度设备。该机器由平衡测量单元、内部搬运系统、切削校正模块及电气控制部分组成&#xff0c;专为满足自动化生产需求设计。其主要功能特点包括&#xff1a; 1. 实现全自动刹车盘平衡测试&#xff0c;精度高达30gm…

vue3 ts 报错:无法找到模块“../views/index/Home.vue”的声明文件

解决办法&#xff1a; env.d.ts 新增代码片段&#xff1a; declare module "*.vue" {import type { DefineComponent } from "vue";// eslint-disable-next-line typescript-eslint/no-explicit-any, typescript-eslint/ban-typesconst component: Define…

ExtruOnt——为工业 4.0 系统描述制造机械类型的本体

概述 论文地址 &#xff1a;https://arxiv.org/abs/2401.11848 原文地址&#xff1a;https://ai-scholar.tech/articles/ontology/ExtruOnt 在工业 4.0 应用场景中&#xff0c;以机器可解释代码提供的、语义丰富的制造机械描述可以得到有效利用。然而&#xff0c;目前显然还缺…

使用nvm安装node包后,安装vue提示“vue不是内部或外部命令,也不是可运行的程序或批处理命令”

前言 使用 npm 安装了 vue-cli 后&#xff0c;输入 "vue -V" 查询vue版本命令提示&#xff1a; “vue不是内部或外部命令,也不是可运行的程序或批处理命令”。 解决方法 第一步&#xff1a;首先&#xff0c;查看 C 盘下有没有 npm 文件夹。 目录类似于&#xff1…

六、数据可视化—Echars(爬虫及数据可视化)

六、数据可视化—Echars&#xff08;爬虫及数据可视化&#xff09; Echarts应用 Echarts Echarts官网&#xff0c;很多图表等都是我们可以 https://echarts.apache.org/zh/index.html 是百度自己做的图表&#xff0c;后来用的人越来越多&#xff0c;捐给了orange组织&#xf…

网络渗透CTF实践:获取靶机Web Developer 文件/root/flag.txt中flag

实验目的&#xff1a;通过对目标靶机的渗透过程&#xff0c;了解CTF竞赛模式&#xff0c;理解CTF涵盖的知识范围&#xff0c;如MISC、PPC、WEB等&#xff0c;通过实践&#xff0c;加强团队协作能力&#xff0c;掌握初步CTF实战能力及信息收集能力。熟悉网络扫描、探测HTTP web服…