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)

相关推荐
猿小喵5 分钟前
DBA之路,始于足下
数据库·dba
tyler_download14 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
编程、小哥哥29 分钟前
设计模式之抽象工厂模式(替换Redis双集群升级,代理类抽象场景)
redis·设计模式·抽象工厂模式
weixin_4493108440 分钟前
高效集成:聚水潭采购数据同步到MySQL
android·数据库·mysql
Cachel wood2 小时前
Github配置ssh key原理及操作步骤
运维·开发语言·数据库·windows·postgresql·ssh·github
standxy2 小时前
如何将钉钉新收款单数据高效集成到MySQL
数据库·mysql·钉钉
Narutolxy3 小时前
MySQL 权限困境:从权限丢失到权限重生的完整解决方案20241108
数据库·mysql
Venchill3 小时前
安装和卸载Mysql(压缩版)
数据库·mysql
Humbunklung3 小时前
一种EF(EntityFramework) MySQL修改表名去掉dbo前缀的方法
数据库·mysql·c#
PGCCC4 小时前
【PGCCC】postgresql 缓存池并发设计
数据库·缓存·postgresql