Spring Boot 中 对话 Redis

Redis 是一款开源的,使用 C 开发的高性能内存 Key/Value 数据库,支持 String、Set、Hash、List、Stream 等等数据类型。它被广泛用于缓存、消息队列、实时分析、计数器和排行榜等场景。基本上是当代应用中必不可少的软件!

Spring Boot 对 Redis 提供了开箱即用的组件:spring-boot-starter-data-redis。通过这个 starter,我们只需要几行简单的配置就可以快速地在 Spring Boot 中整合、使用 Redis。

Spring Boot 整合 Redis

Maven 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

除了 spring-boot-starter-data-redis 外,还添加了 commons-pool2 依赖,是因为我们需要使用到连接池。

配置属性

只需要在 application.yaml | properties 中配置如下常用的基本属性即可:

spring:
    redis:
      # 连接地址
      host: "localhost"
      # 端口
      port: 6379
      # 数据库
      database: 0
      # 用户名,如果有
      # username:
      # 密码,如果有
      # password:
      # 连接超时
      connect-timeout: 5s
      # 读超时
      timeout: 5s

      # Lettuce 客户端的配置
      lettuce:
        # 连接池配置
        pool:
          # 最小空闲连接
          min-idle: 0
          # 最大空闲连接
          max-idle: 8
          # 最大活跃连接
          max-active: 8
          # 从连接池获取连接 最大超时时间,小于等于0则表示不会超时
          max-wait: -1ms

「注意,如果你使用的 不是 spring boot 2.x ,上述配置的命名空间 不应该是 spring.redis 而是 spring.data.redis

使用 Jedis 客户端

Spring Data Redis 默认使用 Lettuce 作为 Redis 客户端。
官方还对 Jedis 提供了支持,你可以根据你的喜好进行选择。
当然推荐在项目中使用 lettuce 客户端,因为它是基于 Netty 开发,支持非阻塞式 IO,性能会更好。

要替换为 Jedis,首先需要从 spring-boot-starter-data-redis 排除 lettuce ,并且添加 jedis 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
    
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

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

然后修改配置文件,把 lettuce 配置替换为 jedis 配置即可:

spring:
  redis:
     # jedis客户端的配置
     jedis:
        # 连接池配置
        pool:
          # 最小空闲连接
          min-idle: 0
          # 最大空闲连接
          max-idle: 8
          # 最大活跃连接
          max-active: 8
          # 从连接池获取连接 最大超时时间,小于等于0则表示不会超时
          max-wait: -1ms

使用 StringRedisTemplate

配置就绪后,StringRedisTemplate 已经可用,你可以在任何地方注入、使用:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {

    static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class);

    // 注入 StringRedisTemplate
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    public void test() {
        
        // 设置
        this.stringRedisTemplate.opsForValue().set("title", "spring 中文网", Duration.ofMinutes(5));

        // 读取
        String val = this.stringRedisTemplate.opsForValue().get("title");

        logger.info("value={}", val);
    }
}   

对于 StringRedisTemplate 更完整的方法列表,你可以参阅其 java doc。

自定义 RedisTemplate

如果基本的 StringRedisTemplate 不能满足你的需求,你也可以自定义 RedisTemplate 实现。

例如,我们想要自定义一个 JsonRedisTemplate,用于把任意 Java 对象序列化为 json 数据存储到 Redis,并且也能够把 Redis 中的 json 数据反序列化为任意 Java 对象。

如下:

package com.zcdf.school.components;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

@Component
public class JsonRedisTemplate extends RedisTemplate<String, Object> {
    public JsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) {

        // 构造函数注入 RedisConnectionFactory,设置到父类
        super.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        serializer.setObjectMapper(objectMapper);

        // String 类型的 key/value 序列化
        super.setKeySerializer(StringRedisSerializer.UTF_8);
        super.setValueSerializer(serializer);

        // Hash 类型的 key/value 序列化
        super.setHashKeySerializer(StringRedisSerializer.UTF_8);
        super.setHashValueSerializer(serializer);
    }
}

首先,继承 RedisTemplate<K,V>,泛型 K 表示 Redis Key 类型,一般都是 String,泛型 V 表示 Redis Value 类型,既然我们需要的是一个通用的 JSON Template,所以设置为 Object,Value 值可以是任意对象。

在构造函数中注入 RedisConnectionFactory 设置到父类,「这是必须的」

然后创建GenericJackson2JsonRedisSerializer 实例,它是基于 Jackson 的 RedisSerializer 实现,用于任意 Java 对象和 JSON 字符串之间的序列化/反序列化。使用该实例作为普通 Value 和 Hash Value 的序列化/反序列化器。注意,因为序列化的对象可能包含了 java.time 类型的日期字段,如:LocalTimeLocalDate 以及 LocalDateTime,所以需要注册 JavaTimeModule

创建测试类进行测试。如下:

    @GetMapping("/eee")
    public int www() {
        System.out.println("测试方法开始执行:");

        // Map
        Map<String, Object> map = new HashMap<>();
        map.put("name", "wtt");
        map.put("url", "https://*****.cn");
        map.put("createAt", LocalDateTime.now());

        jsonRedisTemplate.opsForValue().set("key1-map", map, Duration.ofMinutes(5));

        Map<String, Object> map2 = (Map<String, Object>) jsonRedisTemplate.opsForValue().get("key1-map");
        System.out.println(map2);


        // Hash
        // 设置
        this.jsonRedisTemplate.opsForHash().put("key2-hash", "app", map);
        // 读取
        map = (Map<String, Object>) this.jsonRedisTemplate.opsForHash().get("key2-hash", "app");

        log.info("map={}", map);

        return 0;
    }

我们创建了一个 Map<String, Object> 对象,存储了 2 个 String 和一个 LocalDateTime 字段。然后使用 JsonRedisTemplate 把它存储为普通 Value 和 Hash Value。

存储成功后,再进行读取,反序列化为原来的 Map<String, Object> 对象。

运行测试,执行日志如下:

测试方法开始执行:
{name=wtt, url=https://*****.cn, createAt=[2024, 5, 21, 15, 22, 40, 807000000]}
2024-05-21 15:22:41.079  INFO 7316 --- [nio-8888-exec-1] com.zcdf.school.controller.Testwtt       : map={name=wtt, url=https://*****.cn, createAt=[2024, 5, 21, 15, 22, 40, 807000000]}

我们发现,序列化为 JSON、反序列化为对象都没问题。

好文分享,一起努力加油。

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot可以通过Spring Data Redis来整合Redis。 首先,在pom.xml添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 然后,在application.properties文件配置Redis连接信息: ```properties # Redis配置 spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= spring.redis.database=0 ``` 接下来,在Spring Boot应用使用Redis,可以通过注入StringRedisTemplate或RedisTemplate来实现: ```java @Service public class RedisService { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate<String, Object> redisTemplate; public void setValue(String key, String value) { stringRedisTemplate.opsForValue().set(key, value); } public String getValue(String key) { return stringRedisTemplate.opsForValue().get(key); } public void setObject(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object getObject(String key) { return redisTemplate.opsForValue().get(key); } } ``` 以上示例,StringRedisTemplate用于操作字符串类型的数据,而RedisTemplate用于操作其他类型的数据。 最后,可以通过使用Redis命令行工具来验证Redis是否正常工作。例如,可以使用以下命令在Redis设置一个键值对: ``` > set testKey testValue OK ``` 然后,在Spring Boot应用调用RedisService的getValue方法,可以获取到该键对应的值: ```java String value = redisService.getValue("testKey"); System.out.println(value); // 输出:testValue ``` 注意:在使用Redis时,需要注意数据类型的匹配问题,否则可能会出现数据转换异常等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值