跳到主要内容

5. Micronaut Data Hibernate Reactive

Hibernate Reactive 为传统的JPA带来了响应性。

通过将 Hibernate Reactive 与 Micronaut Data 结合使用,你可以使用与仓库、JPA 标准等相同的功能,但却是以一种响应的方式。

有关 Hibernate Reactive 的更多信息,参阅官方文档

包括 Hibernate Reactive Micronaut Data 支持:

implementation("io.micronaut.data:micronaut-data-hibernate-reactive")
提示

Micronaut Data 中的 Hibernate Reactive 需要 Hibernate 6。

配置与普通的 Hibernate 快速入门不同,因为 Hibernate Reactive 使用的不是传统的 JDBC 驱动,而是 Vertx 项目提供的自定义驱动。你需要为你的数据库选择一个合适的驱动:

对于 MySQL:

implementation("io.vertx:vertx-mysql-client")

对于 Postgres:

implementation("io.vertx:vertx-pg-client")

对于 Microsoft SQLServer:

implementation("io.vertx:vertx-mssql-client")

对于 Oracle:

implementation("io.vertx:vertx-oracle-client")

并基于 Micronaut SQL Hibernate Reactive 支持进行配置。

jpa.default.reactive=true
jpa.default.properties.hibernate.hbm2ddl.auto=create-drop
jpa.default.properties.hibernate.show_sql=true
jpa.default.properties.hibernate.connection.url=jdbc:mysql://localhost:3307/my_db
jpa.default.properties.hibernate.connection.username=myUser
jpa.default.properties.hibernate.connection.password=myPassword

Hibernate 反应式是非阻塞的,你定义的仓资源库接口和类都会扩展其中一个响应式仓库:

表 1. 内置响应式仓库接口

接口描述
ReactiveStreamsCrudRepository扩展了 GenericRepository,并添加了返回 Publisher 的 CRUD 方法
ReactorCrudRepository扩展了 ReactiveStreamsCrudRepository,并使用了 Reactor 返回类型
RxJavaCrudRepository扩展 GenericRepository 并添加可返回 RxJava 2 类型的 CRUD 方法
CoroutineCrudRepository扩展了 GenericRepository,并使用 Kotlin 例程进行反应式 CRUD 操作
ReactiveStreamsJpaSpecificationExecutor响应式 JPA 标准执行器
ReactorJpaSpecificationExecutor使用 Reactor Flux/Mono 类公开方法的响应式 JPA 标准执行器

下面是一个 Hibernate Reactive 仓库示例:

@Repository // (1)
interface BookRepository extends ReactorCrudRepository<Book, Long> { // (2)

Mono<Book> find(String title);

Mono<BookDTO> findOne(String title);

Flux<Book> findByPagesGreaterThan(int pageCount, Pageable pageable);

Mono<Page<Book>> findByTitleLike(String title, Pageable pageable);

Mono<Slice<Book>> list(Pageable pageable);

@Transactional
default Mono<Void> findByIdAndUpdate(Long id, Consumer<Book> bookConsumer) {
return findById(id).map(book -> {
bookConsumer.accept(book);
return book;
}).then();
}

Mono<Book> save(Book entity);

Mono<Book> update(Book newBook);

Mono<Void> update(@Id Long id, int pages);

@Override
Mono<Long> deleteAll();

Mono<Void> delete(String title);
}
  1. 接口使用 @Repository 进行注解
  2. ReactorCrudRepository 接口接受 2 个通用参数,即实体类型(此处为 Book)和 ID 类型(此处为 Long)。

保存实例(创建)

要保存实例,请使用 ReactorCrudRepository 接口的 save 方法:

Book book = new Book();
book.setTitle("The Stand");
book.setPages(1000);
bookRepository.save(book).block();

检索实例(读取)

要回读一个 book,请使用 findById

book = bookRepository.findById(id).block();

更新实例(更新)

要更新实例,我们使用自定义方法在事务中进行更新:

bookRepository.findByIdAndUpdate(id) {
it.title = "Changed"
}.block()

删除实例(删除)

要删除一个实例,请使用 deleteById

bookRepository.deleteById(id).block();
注意

这些示例使用 block 来检索结果,在您的应用程序中,您绝对不应该阻塞反应式存储库,因为这可能会导致性能问题,而且后盾实现可能也不支持这种阻塞。

英文链接