Redis整合springboot笔记

redis整合springboot学习笔记

pom引入依赖

需要同时引入spring-boot-starter-data-redis和commons-pool2这2个依赖;

spring-boot-starter-data-redis是官方封装的redis操作依赖,

commons-pool2是redis需要的连接池,不引入这个会导致启动报错.

xml 复制代码
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.5.0</version>
        </dependency>

配置springboot项目内的application.yml或application.properties

yaml 复制代码
spring:
  redis:
    # ip
    host: localhost
    # 端口6379
    port: 6379
    #密码,没有密码则不配置这一项
    password:
    #指定使用redis 16个库中的哪一个,不配置的话,默认配置为0
    database: 0
    lettuce:
      pool:
        min-idle: 0   #连接池最新空闲时间
        max-wait: -1ms  #最大等待时间
        max-active: 8   #最大活跃时间
        max-idle: 8    #最大空闲时间
      shutdown-timeout: 100ms  #连接池关闭超时时间
    timeout: 1000ms  #redis连接超时时间

使用spring-boot-starter-data-redis内置的StringRedisTemplate

要在需要使用redis的地方注入StringRedisTemplate,如

java 复制代码
@Slf4j
@Component
@Validated
public class RedisTool {
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }
    private ObjectMapper objectMapper;
     @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

}    

判断key是否存在

java 复制代码
 public boolean hasKey(@NotNull String strK) {
        Boolean hasKey = stringRedisTemplate.hasKey(strK);
        if (hasKey != null && hasKey) {
            return true;
        } else {
            log.warn("不存在redis key:{}",strK);
            return false;
        }
    }

删除key

java 复制代码
//删除1个key
public void deleteOneKeyIfExist(@NotNull String key) {
        if (this.hasKey(key)) {
            Boolean delete = stringRedisTemplate.delete(key);
            log.info("删除了key:{},删除结果:{}",key, delete);
        }
    }

//删除多个key
public void deleteBatchKeyIfExist(Set<String> keySet) {
        for (String k : keySet) {
            this.deleteOneKeyIfExist(k);
        }
    }    

添加key

java 复制代码
//添加固定的key
public void setKV(@NotNull String strK, String plainStrV) {
        stringRedisTemplate.opsForValue().set(strK, plainStrV);
    }
//添加带超时时间的key,超时时间到期后key会自动删除
    public void setKVTimeoutSeconds(@NotNull String strK, String plainStrV, long seconds) {
        stringRedisTemplate.opsForValue().set(strK, plainStrV, seconds, TimeUnit.SECONDS);
    }
    
    //序列化后 进行set key
    public boolean setKeyAndObjValue(@NotNull String strK, @NotNull Object objV) {
        try {
            String s = objectMapper.writeValueAsString(objV);
            log.warn("jackson序列化:{}", s);
            this.setKV(strK, s);
            return true;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("jackson序列化失败", e);
            return false;
        }
    }


    public boolean setKeyAndObjValueByTimeoutSeconds(@NotNull String strK, @NotNull Object objV, long seconds) {
        try {
            String s = objectMapper.writeValueAsString(objV);
            log.warn("jackson序列化:{}", s);
            this.setKVTimeoutSeconds(strK, s, seconds);
            return true;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("jackson序列化失败", e);
            return false;
        }
    }

查询key

java 复制代码
//获取key的字符串值
public String getPlainStrV(@NotNull String srtKey) {
        if (!this.hasKey(srtKey)) {
            return null;
        }
        return stringRedisTemplate.opsForValue().get(srtKey);
    }

//获取key的对象值
    public <T> T getJavaObjByJsonCache(@NotNull String srtKey, Class<T> valueType) {
        if (!this.hasKey(srtKey)) {
            return null;
        }
        String str = stringRedisTemplate.opsForValue().get(srtKey);
        if (StrUtil.isBlank(str)) {
            return null;
        }
        try {
            log.warn("反序列化json str:{} 为Java obj type:{}", str,valueType);
            return objectMapper.readValue(str, valueType);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("json str 反序列化失败", e);
            return null;
        }
    }

通过redis中的pub/sub实现消息发布和订阅

定义RedisPubSubCfg

java 复制代码
package cn.test.redis;
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.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;


@Configuration
public class RedisPubSubCfg {

   private final RedisConnectionFactory redisConnectionFactory;
   @Autowired
   public RedisPubSubCfg(RedisConnectionFactory redisConnectionFactory) {
       this.redisConnectionFactory = redisConnectionFactory;
   }

   /**
    * 将消息监听器绑定到消息容器
    * @return RedisMessageListenerContainer
    */
   @Bean
   public RedisMessageListenerContainer messageListenerContainer(){
       RedisMessageListenerContainer container = new RedisMessageListenerContainer();
       container.setConnectionFactory(redisConnectionFactory);

       //------分开订阅监听,使用自定义的消息监听器SubscribeListener-------
       //按名称匹配
       container.addMessageListener(new CitySub(),new ChannelTopic("cityTopic"));
       //按模式匹配
       container.addMessageListener(new TestSub(),new PatternTopic("/aaa/*"));

       return container;
   }

}

自定义消息监听器

java 复制代码
package cn.test.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

@Slf4j
public class TestSub implements MessageListener {
  
    @Override
    public void onMessage(Message message, byte[] pattern) {

        String s = new String(pattern);
        log.info("redis  sub pattern: "+s);

        String channelReal = new String(message.getChannel());
        log.info("real sub pattern: "+channelReal);

        String body = new String(message.getBody());
        log.info("TestSub 订阅到的消息: "+body);

    }
}


package cn.test.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

@Slf4j
public class CitySub implements MessageListener {
  
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String body = new String(message.getBody());

        String channel = new String(message.getChannel());
        System.err.println("Topic 名称: "+channel);
        String patternStr = new String(pattern);
        System.err.println("Topic 模式: "+patternStr);
        log.info("CitySub 订阅到的消息: {}",body);
    }
}
相关推荐
焗猪扒饭4 小时前
redis stream用作消息队列极速入门
redis·后端·go
用户9083246027316 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
齐生117 小时前
iOS 知识点 - IAP 是怎样的?
笔记
tingshuo29171 天前
D006 【模板】并查集
笔记
用户8307196840821 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解2 天前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解2 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记2 天前
Spring Boot Web MVC配置详解
spring boot·后端
tingshuo29172 天前
S001 【模板】从前缀函数到KMP应用 字符串匹配 字符串周期
笔记
雨中飘荡的记忆2 天前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端