web-dev-qa-db-ja.com

リアクティブなSpring Dataでページ分割をどのように適用しますか?

Spring Dataには、PagingAndSortingRepositoryを継承するCrudRepositoryがあります。リアクティブなSpring Dataでは、ReactiveSortingRepositoryから継承するReactiveCrudRepositoryのみが存在します。どのようにして反応的な方法でページ付けを行うことができますか?将来、たとえばReactivePagingAndSortingRepositoryを使用してこれを作成できますか?

11
Steph

Reactive Spring Data MongoDBリポジトリーは、命令型リポジトリー用に設計されたページングという意味ではページングを提供しません。命令型ページングでは、ページのフェッチ中に追加の詳細が必要です。特に:

  • ページングクエリで返されたレコードの数
  • 必要に応じて、返されたレコードの数がゼロであるか、ページサイズと一致して全体のページ数を計算する場合にクエリが生成するレコードの総数

どちらの側面も、効率的な非ブロッキングリソースの使用という概念には適合しません。すべてのレコードが受信されるまで(ページング詳細の最初のチャンクを決定するために)待機すると、事後対応データアクセスによって得られる利点の大部分が削除されます。さらに、カウントクエリの実行にはかなりの負荷がかかり、データを処理できるようになるまでの遅延が長くなります。

リポジトリクエリメソッドにPageablePageRequest)を渡すことで、データのチャンクを自分でフェッチすることもできます。

interface ReactivePersonRepository extends Repository<Person, Long> {

  Flux<Person> findByFirstnameOrderByLastname(String firstname, Pageable pageable);
}

Spring Dataは、PageableLIMITおよびOFFSETに変換することにより、クエリにページ分割を適用します。

参照:

13
mp911de
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);
}

詳細、 ここで確認できます

5
kn3l

私はまだ解決策を探している可能性がある人のためにこの方法でサービスを作成しました:

@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));
                });
    }
0
Sam1am

@ kn3lソリューションを使用して別のアプローチを作成しました(@Queryを使用せずに):

fun findByIdNotNull(page: Pageable): Flux< Quote>

@Queryメソッドを使用せずに同じクエリを作成します