面向小白的Ractive方式访问redis

1,057 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

昨天简单演示了一下Reactor,今天我们来看看这种方式是怎么操作redis的,操作方法和之前无较大差别,只不过是把原来同步的方式,变为异步执行了而已。、

搞配置

我们要操作redis,所以需要redis的支持,数据是从数据库查的,所以需要jdbc的支持,我们需要导入依赖:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

需要指定redis的位置spring.redis.host。

搞代码

我们需要ReactiveStringRedisTemplate的支持,但是并没有提供,因此我们需要自己定义一个

@Bean
ReactiveStringRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) {
    return new ReactiveStringRedisTemplate(factory);
}

我们可以看到这个工厂里面有我们需要的redis的连接。 image.png

使用共享锁CountDownLatch,因为我们这个操作是一组,是由两个线程完成的,所以任务数就给1.然后为了看效果,打印一个等待信息。

CountDownLatch cdl = new CountDownLatch(1);
log.info("Waiting");
cdl.await();

查询数据,这个很简单:就是一个函数式接口映射对象

List<Coffee> list = jdbcTemplate.query(
        "select * from t_coffee", (rs, i) ->
        Coffee.builder()
                .id(rs.getLong("id"))
                .name(rs.getString("name"))
                .price(rs.getLong("price"))
                .build()
);

遍历列表,以流的方式并在单线程中执行:

Flux.fromIterable(list)
        .publishOn(Schedulers.single())
        .doOnComplete(() -> log.info("list ok"))

以流的方式一一映射存入redis中

ReactiveHashOperations<String, String, String> hashOps = redisTemplate.opsForHash()
.flatMap(c -> {
    log.info("try to put {},{}", c.getName(), c.getPrice());
    return hashOps.put(KEY, c.getName(), c.getPrice().toString());
})

完成之后,打印ok,紧接着设置key的过期时间

.doOnComplete(() -> log.info("set ok"))
.concatWith(redisTemplate.expire(KEY, Duration.ofMinutes(1)))
.doOnComplete(() -> log.info("expire ok"))

然后我们订阅,看订阅是否成功,然后任务完成。

.subscribe(b -> log.info("Boolean: {}", b),
        e -> log.error("Exception {}", e.getMessage()),
        () -> cdl.countDown());

可以看到这个订阅都是成功的,状态都是正确的。

image.png

其实,和我们前面提到的redis使用差不太多,只是另开启了个线程,然后把原来同步的操作变为异步了,就算是响应式编程的简单示例,你学会了吗?