Redis操作(三)RedisTemplate(2)StringRedisTemplate常见API

RedisTemplate 提供了丰富的方法来实现对 Redis 的各种操作,包括但不限于字符串、哈希、列表、集合和有序集合等数据结构的操作。以下是一些常用的 RedisTemplate API:

一、字符串操作

  • opsForValue().set(key, value): 设置字符串值。

  • opsForValue().get(key): 获取字符串值。

  • opsForValue().incr(key): 字符串值自增。

  • opsForValue().decr(key): 字符串值自减。

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

      @Test
      public void  testString(){
          String key = "string-name";
          //存
          String value = "这是value123";
          stringRedisTemplate.opsForValue().set(key,value);
          //取
          Object valueObj = stringRedisTemplate.opsForValue().get(key);
          System.out.println("value为:" + valueObj);
      }
    

    import com.alibaba.fastjson.JSON;
    import org.example.Main;
    import org.example.dto.UserDTO;
    import org.example.service.UserService;
    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.StringRedisTemplate;
    import org.springframework.test.context.junit4.SpringRunner;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

      @Test
      public void  testUser(){
          String key = "user-key";
          //存
          UserDTO userDTO = new UserDTO();
          userDTO.setUserAccount("zhangsan");
          userDTO.setAge(18);
          userDTO.setUserName("张三");
          stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(userDTO));
          //取
          String valueObj = stringRedisTemplate.opsForValue().get(key);
          UserDTO redisUser = JSON.parseObject(valueObj, UserDTO.class);
          System.out.println("value为:" + redisUser);
      }
    

二、哈希操作

opsForHash().getOperations().put(key, hashKey, value): 向哈希中添加键值对。

opsForHash().getOperations().get(key, hashKey): 获取哈希中的值。

opsForHash().getOperations().entries(key): 获取哈希中的所有键值对。

三、列表操作

opsForList().leftPush(key, value): 从列表左侧添加元素。

opsForList().rightPush(key, value): 从列表右侧添加元素。

opsForList().leftPop(key): 从列表左侧弹出元素。

opsForList().rightPop(key): 从列表右侧弹出元素。

四、集合操作

  • opsForSet().add(key, value): 向集合中添加元素。
  • opsForSet().members(key): 获取集合中的所有元素。
  • opsForSet().remove(key, value): 从集合中移除元素。

五、有序集合操作

opsForZSet().add(key, value, score): 向有序集合中添加元素,并指定分数。

opsForZSet().range(key, start, end): 获取有序集合中指定分数范围内的元素。

opsForZSet().removeRangeByScore(key, minScore, maxScore): 按分数范围移除有序集合中的元素。

六、键操作

  • delete(key): 删除键。
  • hasKey(key): 检查键是否存在。
  • keys(pattern): 根据模式匹配获取所有键。

七、执行命令(事务操作)

  • execute():用于在 Redis 连接上执行单个 Redis 命令,并返回执行命令后的结果。该方法执行完后会自动关闭 Redis 连接。
  • executePipelined ():相比之下,executePipelined() 方法用于一次性在 Redis 连接上执行多个 Redis 命令,使用管道(pipeline)方式进行优化,减少网络 I/O 开销。与 execute() 方法不同的是,executePipelined() 方法返回的是一个 Redis 命令结果列表,而不是单个命令的结果对象。在执行多个 Redis 命令时,可以使用 executePipelined() 方法来提高性能和效率。

当数据量较小时,使用 RedisCallback 和 SessionCallback 性能表现相近是可以理解的,因为此时 Redis 执行单个命令的时间较短,差异不大。但是当数据量增多时,SessionCallback 的优势会更加明显,因为当有多个 Redis 命令需要保持一致性时,使用 RedisCallback 会在执行每个 Redis 命令时都进行连接的获取和释放,而使用 SessionCallback 则可以通过事务管理器提供的 Redis 连接来执行多个 Redis 命令,减少了连接的获取和释放次数,从而提高了性能。

对比维度 execute() executePipelined()
执行方式 逐个执行 Redis 命令 将多个 Redis 命令封装在管道内,一次性提交
返回结果 根据具体 Redis 命令返回不同类型的结果 返回多个 Redis 命令的执行结果列表
执行效率 较慢,需要频繁的连接获取和释放 快,将多个 Redis 命令封装在一个管道内,减少连接数
使用场景 需要手动管理 Redis 连接或者执行单个 Redis 命令时 需要高性能地执行多个 Redis 命令时
this.stringRedisTemplate.execute(
                    (RedisCallback<Long>)
                            (connection) -> {
                                return connection.del(keysByte);
                            });

八、广播发布/订阅

  • convertAndSend(channel, message): 发布消息。
  • subscribe(RedisMessageListenerContainer, MessageListener): 订阅消息。

(1)发送消息:

stringRedisTemplate.convertAndSend

(2)接收消息:

① implements MessageListener来实现一个监听器;

② 注册监听器到RedisMessageListenerContainer中。

demo:

(1)监听器:如我有两个监听器

package org.example.listen;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.dto.UserDTO;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RedisBroadcastUserMsgHandler implements MessageListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String consumerChannel = RedisSerializer.string().deserialize(message.getChannel());
        if(!consumerChannel.equals("user-topic")){
            return;
        }
        byte[] body = message.getBody();
        String json = RedisSerializer.string().deserialize(body);
        UserDTO userDTO = JSON.parseObject(json,UserDTO.class);
        log.info("handle接收到:"+userDTO);
    }
}

package org.example.listen;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.dto.UserDTO;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RedisBroadcastUserMsgTwoHandler implements MessageListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String consumerChannel = RedisSerializer.string().deserialize(message.getChannel());
        if(!consumerChannel.equals("user-topic-two")){
            return;
        }
        byte[] body = message.getBody();
        String json = RedisSerializer.string().deserialize(body);
        UserDTO userDTO = JSON.parseObject(json,UserDTO.class);
        log.info("handle接收到:"+userDTO);
    }
}

(2)注册监听器

package org.example.config;

import lombok.extern.slf4j.Slf4j;
import org.example.listen.RedisBroadcastUserMsgHandler;
import org.example.listen.RedisBroadcastUserMsgTwoHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import java.util.List;

@Slf4j
@Configuration
public class RedisListenerConfig {

    @Autowired
    private RedisBroadcastUserMsgHandler userMsgHandler;

    @Autowired
    private RedisBroadcastUserMsgTwoHandler twoHandler;

    @Bean
    public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(userMsgHandler, new ChannelTopic("user-topic"));
        container.addMessageListener(twoHandler, new ChannelTopic("user-topic-two"));
        return container;
    }
}

(3)发送消息

    @Autowired
    private StringRedisTemplate stringRedisTemplate;  

    @Test
    public void  testSendMsg(){
        UserDTO userDTO = new UserDTO();
        userDTO.setUserAccount("zhangsan");
        userDTO.setAge(18);
        userDTO.setUserName("张三");
        String channel = "user-topic";
        stringRedisTemplate.convertAndSend(channel,JSON.toJSONString(userDTO));
        //
        String channelTwo = "user-topic-two";
        stringRedisTemplate.convertAndSend(channelTwo,JSON.toJSONString(userDTO));
    }

执行控制台打印:

2024-08-13T16:04:31.630+08:00  INFO 10496 --- [edisContainer-2] o.e.l.RedisBroadcastUserMsgTwoHandler    : handle接收到:UserDTO(userName=张三, age=18, userAccount=zhangsan)
2024-08-13T16:04:31.630+08:00  INFO 10496 --- [edisContainer-1] o.e.listen.RedisBroadcastUserMsgHandler  : handle接收到:UserDTO(userName=张三, age=18, userAccount=zhangsan)
改进demo

如果有多个消费者,注册会比较麻烦,因此对上述监听器代码封装下:

(1)监听器:

package org.example.listen;

import org.springframework.data.redis.connection.MessageListener;

public abstract class RedisListener implements MessageListener {
    public abstract String getTopic();
}

package org.example.listen;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.dto.UserDTO;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RedisBroadcastUserMsgHandler extends RedisListener {



    @Override
    public String getTopic() {
        return "user-topic";
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        byte[] body = message.getBody();
        String json = RedisSerializer.string().deserialize(body);
        UserDTO userDTO = JSON.parseObject(json,UserDTO.class);
        log.info("handle接收到:"+userDTO);
    }
}

package org.example.listen;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.dto.UserDTO;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RedisBroadcastUserMsgTwoHandler extends RedisListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        byte[] body = message.getBody();
        String json = RedisSerializer.string().deserialize(body);
        UserDTO userDTO = JSON.parseObject(json,UserDTO.class);
        log.info("handle接收到:"+userDTO);
    }

    @Override
    public String getTopic() {
        return "user-topic-two";
    }
}

(2)注册监听器:

package org.example.config;

import lombok.extern.slf4j.Slf4j;
import org.example.listen.RedisBroadcastUserMsgHandler;
import org.example.listen.RedisBroadcastUserMsgTwoHandler;
import org.example.listen.RedisListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import java.util.List;

@Slf4j
@Configuration
public class RedisListenerConfig {

    @Autowired
    private RedisBroadcastUserMsgHandler userMsgHandler;

    @Autowired
    private List<RedisListener> redisListeners;

    @Bean
    public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        for(RedisListener listener : redisListeners) {
            container.addMessageListener(listener, new ChannelTopic(listener.getTopic()));
        }
        return container;
    }
}

执行Test:

@Test
    public void  testSendMsg(){
        UserDTO userDTO = new UserDTO();
        userDTO.setUserAccount("zhangsan");
        userDTO.setAge(18);
        userDTO.setUserName("张三");
        String channel = "user-topic";
        stringRedisTemplate.convertAndSend(channel,JSON.toJSONString(userDTO));
        //
        userDTO.setUserAccount("zhangsan-two");
        userDTO.setUserName("张三-two");
        String channelTwo = "user-topic-two";
        stringRedisTemplate.convertAndSend(channelTwo,JSON.toJSONString(userDTO));
    }

打印:

2024-08-13T16:25:10.725+08:00  INFO 88872 --- [edisContainer-1] o.e.listen.RedisBroadcastUserMsgHandler  : handle接收到:UserDTO(userName=张三, age=18, userAccount=zhangsan)
2024-08-13T16:25:10.725+08:00  INFO 88872 --- [edisContainer-2] o.e.l.RedisBroadcastUserMsgTwoHandler    : handle接收到:UserDTO(userName=张三-two, age=18, userAccount=zhangsan-two)

九、连接管理

  • getConnectionFactory(): 获取连接工厂。
  • getExecutor(): 获取执行器。

十、序列化

  • setKeySerializer(Serializer): 设置键的序列化器。
  • setValueSerializer(Serializer): 设置值的序列化器。

更多操作可以查看官方提供的API文档:RedisTemplate (Spring Data Redis 3.3.2 API)

相关推荐
正在走向自律14 分钟前
1.MySQL存储过程基础(1/10)
数据库·mysql·存储过程
gbase_lmax1 小时前
gbase8s数据库实现黑白名单的几种方案
数据库
“抚琴”的人1 小时前
SQL Server—的数据类型
数据库·sql
青云交2 小时前
大数据新视界 --大数据大厂之 Presto 性能优化秘籍:加速大数据交互式查询
大数据·数据库·性能优化·presto·数据一致性·查询优化·交互式查询·传统查询工具
ldj20202 小时前
Docker 搭建mysql 连接超时问题,xxl-job启动mysql连接报错
数据库·mysql
军大君2 小时前
HexHub | 一款强大的SSH/SFTP、数据库、Docker 跨平台桌面客户端
数据库·mysql·docker·ssh·finalsheel
黑龙江亿林等保2 小时前
等保测评是什么?为什么要做等保测评?
运维·网络·数据库
小小不董3 小时前
《Linux从小白到高手》理论篇:一文概览常用Linux重要配置文件
linux·运维·服务器·数据库·dba
肥or胖3 小时前
【MySQL】复合查询
linux·数据库·mysql
fishmemory7sec3 小时前
Koa2项目实战3 (koa-body,用于处理 HTTP 请求中的请求体)
数据库·mongodb·koa·koa-body