我正在使用 ReactiveCassandraRepository,我可以创建新记录,如下所示。
public Mono<String> saveAbc(Abc toBeSaved) {
return abcRepository.save(toBeSaved).map(saved -> saved.getId());
}
但是我无法想象如何更新数据库记录中的特定字段,因为涉及到 2 个 react 性操作(findById 和 save)。
我编写了如下代码来创建或更新状态(如果存在),但似乎不起作用。
public Mono<String> saveAbc(Abc toBeSaved) {
return abcRepository.findById(toBeSaved.getId())
.map(current -> abcRepository.save(transform(toBeSaved, current)).map(saved -> saved.getId()))
.flatMap(id -> id);
}
private Abc transform(Abc toBeSaved, Abc current) {
if(current == null) {
return toBeSaved;
} else {
current.setStatus(toBeSaved.getStatus());
return current;
}
}
有人可以帮忙吗?
最佳答案
我希望你的 abcRepository 的方法看起来像这样:
interface AbcRepository {
Mono<Abc> findById(String id);
Mono<Abc> save(Abc abc);
}
我从你的代码中猜测,对于给定的 Abc 你想要
- 从存储库中读取具有相同 ID 的 Abc,
- 将数据从给定的 Abc 映射到找到的数据,
- 或者如果存储库没有找到任何内容,则仅使用给定的 Abc,
- 异步保存此 Abc
- 并将保存的元素的 id 返回为 Mono
我会这样做:
public Mono<String> saveAbc(Abc toBeSaved) {
return abcRepository.findById(toBeSaved.getId()) // (1)
.map(abc -> transform(toBeSaved, abc)) // (2)
.defaultIfEmpty(toBeSaved) // (3)
.flatMap(abcRepository::save) // (4)
.map(Abc::getId); // (5)
}
private Abc transform(Abc toBeSaved, Abc current) {
current.setStatus(toBeSaved.getStatus());
return current;
}
Mono 只能接收一个元素或不接收任何元素,因此使用 Mono:map (2) 时不需要处理 null 值。 abcRepository 返回的 Mono 将接收找到的 Abc,在这种情况下转换调用 (2) 已完成,或者它只会发出一个完整信号,在这种情况下映射不执行任何操作,defaultIfEmpty (3) 发出 toBeSaved 作为后备。
如果您有一个本身异步的转换,从而导致另一个 Mono 使用 flatMap (4),否则您的中间结果将是 Mono<Mono<Abc>>
.
永远记住:在调用 subscribe 之前什么都不会发生。
saveAbc(myNewAbc).subscribe(id -> System.out.println("Saved Abc with id: " + id));
<小时/>
在上面的示例中,我希望您的存储库在 findById 找不到任何匹配的 Abc 来将 Mono 补全为空时发出完整信号(使用 ReactiveCassandraRepository 时就是这种情况!)。如果在这种情况下存储库发出异常,您可以使用
.onErrorResume(t -> Mono.just(toBeSaved))
而不是 defaultIfEmpty
(3).
关于java - 如何在 react 器中编码以更新 cassandra 数据库记录中的特定字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51100377/