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)

相关推荐
DarkAthena37 分钟前
【ORACLE】记录一些ORACLE的merge into语句的BUG
数据库·oracle·bug
大新新大浩浩1 小时前
arm64适配系列文章-第三章-arm64环境上mariadb的部署
数据库·arm·mariadb
聪明的墨菲特i1 小时前
SQL进阶知识:九、高级数据类型
xml·数据库·sql·mysql·json·空间数据类型
oioihoii1 小时前
金仓数据库 KingbaseES 产品深度优化提案:迈向卓越的全面升级
数据库·性能优化·金融·金仓数据库 2025 征文·数据库平替用金仓
艺杯羹1 小时前
JDBC 批处理与事务处理:提升数据操作效率与一致性的密钥
数据库·mysql·jdbc·事务处理·批处理数据
猫咪-95272 小时前
【金仓数据库征文】——选择金仓,选择胜利
数据库·金仓数据库 2025 征文·数据库平替用金仓
努力进修3 小时前
【金仓数据库征文】-金仓数据库性能调优 “快准稳” 攻略:实战优化,让数据处理飞起来
数据库·人工智能·金仓数据库 2025 征文·数据库平替用金仓
User_芊芊君子4 小时前
【金仓数据库征文】金仓数据库KingbaseES:千行百业国产化征程中的璀璨之星
数据库·数据库平替用金仓·金仓数据库2025征文
User_芊芊君子5 小时前
【金仓数据库征文】金仓数据库KingbaseES:在技术与人文交织中开拓信创未来
数据库·数据库平替用金仓·金仓数据库2025征文
傻啦嘿哟6 小时前
Python正则表达式:用“模式密码“解锁复杂字符串
linux·数据库·mysql