Spring Dataには、PagingAndSortingRepository
を継承するCrudRepository
があります。リアクティブなSpring Dataでは、ReactiveSortingRepository
から継承するReactiveCrudRepository
のみが存在します。どのようにして反応的な方法でページ付けを行うことができますか?将来、たとえばReactivePagingAndSortingRepository
を使用してこれを作成できますか?
Reactive Spring Data MongoDBリポジトリーは、命令型リポジトリー用に設計されたページングという意味ではページングを提供しません。命令型ページングでは、ページのフェッチ中に追加の詳細が必要です。特に:
どちらの側面も、効率的な非ブロッキングリソースの使用という概念には適合しません。すべてのレコードが受信されるまで(ページング詳細の最初のチャンクを決定するために)待機すると、事後対応データアクセスによって得られる利点の大部分が削除されます。さらに、カウントクエリの実行にはかなりの負荷がかかり、データを処理できるようになるまでの遅延が長くなります。
リポジトリクエリメソッドにPageable
(PageRequest
)を渡すことで、データのチャンクを自分でフェッチすることもできます。
interface ReactivePersonRepository extends Repository<Person, Long> {
Flux<Person> findByFirstnameOrderByLastname(String firstname, Pageable pageable);
}
Spring Dataは、Pageable
をLIMIT
およびOFFSET
に変換することにより、クエリにページ分割を適用します。
参照:
import com.thepracticaldeveloper.reactiveweb.domain.Quote;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import reactor.core.publisher.Flux;
public interface QuoteMongoReactiveRepository extends ReactiveCrudRepository<Quote, String> {
@Query("{ id: { $exists: true }}")
Flux<Quote> retrieveAllQuotesPaged(final Pageable page);
}
詳細、 ここで確認できます
私はまだ解決策を探している可能性がある人のためにこの方法でサービスを作成しました:
@Resource
private UserRepository userRepository; //Extends ReactiveSortingRepository<User, String>
public Mono<Page<User>> findAllUsersPaged(Pageable pageable) {
return this.userRepository.count()
.flatMap(userCount -> {
return this.userRepository.findAll(pageable.getSort())
.buffer(pageable.getPageSize(),(pageable.getPageNumber() + 1))
.elementAt(pageable.getPageNumber(), new ArrayList<>())
.map(users -> new PageImpl<User>(users, pageable, userCount));
});
}
@ kn3lソリューションを使用して別のアプローチを作成しました(@Queryを使用せずに):
fun findByIdNotNull(page: Pageable): Flux< Quote>
@Queryメソッドを使用せずに同じクエリを作成します