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);
    }
}
相关推荐
sam-12324 分钟前
k8s上部署redis高可用集群
redis·docker·k8s
秀儿还能再秀32 分钟前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
WCF向光而行37 分钟前
Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)
笔记·学习
看山还是山,看水还是。1 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
谷新龙0011 小时前
Redis运行时的10大重要指标
数据库·redis·缓存
java—大象1 小时前
基于java+springboot+layui的流浪动物交流信息平台设计实现
java·开发语言·spring boot·layui·课程设计
精进攻城狮@1 小时前
Redis缓存雪崩、缓存击穿、缓存穿透
数据库·redis·缓存
ApiHug2 小时前
ApiSmart x Qwen2.5-Coder 开源旗舰编程模型媲美 GPT-4o, ApiSmart 实测!
人工智能·spring boot·spring·ai编程·apihug
魔道不误砍柴功2 小时前
探秘Spring Boot中的@Conditional注解
数据库·spring boot·oracle
杨哥带你写代码2 小时前
网上商城系统:Spring Boot框架的实现
java·spring boot·后端