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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值