Redis操作--RedisTemplate(二)StringRedisTemplate

一、介绍

1、简介

由于存储在 Redis 中的 key 和 value 通常是很常见的 String 类型,Redis模块提供了 RedisConnection 和 RedisTemplate 的扩展,分是 StringRedisConnection 和 StringRedisTemplate,作为字符串操作的解决方案。

通过源码可以看见对于Key、Value、HashKey、HashValue都是进行String类型的序列化。

因此对于一些复杂类型,如对象在StringRedisTemplate的时候往往需要自己手动序列化将对象转为JSON再存入Redis。

二、集成

使用StringRedisTemplate,不需要(写RedisConfig)额外设置序列化。不过存取对象需要自己序列化、反序列化。

三、使用

1、存取string
复制代码
 @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);
    }

输出:value为:这是value123,

查看可视化工具也没有乱码

2、存取对象
复制代码
    @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);
    }

输出:value为:UserDTO(userName=张三, age=18, userAccount=zhangsan)

查看可视化工具没有乱码:

3、广播消息

(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)
相关推荐
今晚务必早点睡6 小时前
微服务改数据库密码后服务仍能访问?一次“看似异常、实则常见”的生产现象全解析
数据库·微服务·oracle
老师我太想进步了20268 小时前
cmd连接MySQL及相关查询
数据库·mysql
難釋懷11 小时前
Redis命令-Set命令
数据库·redis·缓存
编程小风筝11 小时前
Spring 框架如何整合Redis缓存中间件?
redis·spring·缓存
Linux-palpitate11 小时前
PostgreSQL(PG)的1主2从集群部署安装
数据库·postgresql
heartbeat..12 小时前
数据库基础知识体系:概念、约束、范式与国产产品
java·数据库·学习笔记·国产数据库
山峰哥12 小时前
数据库工程核心:SQL调优让查询效率飙升的实战密码
网络·汇编·数据库·sql·编辑器
Coder_Boy_13 小时前
基于SpringAI的在线考试系统-DDD业务领域模块设计思路
java·数据库·人工智能·spring boot·ddd
小雪_Snow13 小时前
Windows 安装 MySQL 8.0 教程【安装包方式】
数据库·mysql
无敌的牛13 小时前
MySQL初阶
数据库·mysql