如何检查 Spring 反应式应用程序中的现有条目?

How to check for existing entry in a Spring reactive application?

我正在尝试以反应方式(使用 R2DBC)编写一个简单的 REST API,其中包含对存储书籍的数据库的所有 CRUD 操作。使用其中一个定义的端点,应该可以将一本书保存到数据库中。所以我写了下面的代码来保存一本书到数据库:

public Mono<Book> saveBook(Mono<Book> book) throws ResourceAlreadyExistsException {
    return book.doOnNext(b -> log.info("Save book with title " + b.toString()))
               .flatMap(b -> bookRepository.findByTitle(b.getTitle()))
               .switchIfEmpty(Mono.defer(() -> bookRepository.saveAll(book).next()))
               .flatMap(b -> Mono.error(
                        new ResourceAlreadyExistsException(String.format("Book already exists for provided title :: %s" , book.getTitle()))));              
}

所以我首先检查数据库中是否已经存在该书名。如果书不存在,则执行 switchIfEmpty,并存储书。但是在 switchIfEmpty 之后,flatMap 也总是被调用!在上面的代码中,即使一本书存储成功,最后一个平面图也会抛出一个错误。显然我在这里做错了......

我想在我的反应式应用程序中实现以下目标:

  1. 检查书名是否已存在于数据库中
  2. 如果没有,将书存入数据库
  3. 如果该书已经存在,则抛出异常

我希望有人能帮助以干净高效的方式编写这段代码!

我认为最有效的方法是在数据库中使用约束。如果您将书名设置为唯一列,然后尝试保存另一本具有相同书名的书,数据库将抛出异常。

然后您唯一需要做的就是使用 onErrorResume 方法“捕获”此异常并将其转换为您自定义的“ResourceAlreadyExists”异常。