ストリーミングクエリ

以下の findEachfindIteratefindStream はすべてストリーミングクエリであり、主にクロージャー、イテレーター、またはストリームを使用してスタイルが異なります。これらのストリーミングクエリを使用すると、すべての結果をメモリ内に保持せずに非常に大きな結果を処理できます。findEach は、リソースを保持するすべてのクエリを、try with resources ブロックを必要とせずに閉じたままにするため、推奨されるスタイルです。findStreamfindIterate の使用は同様ですが、QueryIterator と ストリームは通常 try with resources を介して閉じたままにする必要があることに注意してください。

Ebean バージョン 12.3.5 から、これらのストリーミングクエリは「適応永続性コンテキスト」を使用します。つまり、findEachfindIteratefindStream は、findList と同様に小さなクエリ結果に対しても同様に機能します。処理された Bean が 1000 個になると、クエリは使用する永続性コンテキストを調整して、すべての Bean を保持しないようにします(非常に大きな結果を処理する場合はメモリ不足になります)。

1000 個未満の Bean を処理するクエリは、単一の通常の永続性コンテキストを使用します。1000 個以上の Bean がある場合、永続性コンテキストは調整され、すべての Bean を保持しないようになります。

findEach

一度に 1 つずつ Bean を処理してクエリを実行します。

new QCustomer()
 .status.equalTo(Status.NEW)
 .order().id.asc()
 .findEach((Customer customer) -> {

   // do something with customer
   System.out.println("-- visit " + customer);
 });

findEachWhile

findEach のようなものですが、結果を早く処理することを停止できる述語を使用します。

// Returning false inside the predicate will stop the execution
new QCustomer()
   .status.equalTo(Status.NEW)
   .order().id.asc()
   .findEachWhile((Customer customer) -> {
     // do something with customer
     ...
     // return true to continue processing or false to stop
     return (customer.getId() < 40);
   });

バッチコンシューマーを使用した findEach

findEach と似ていますが、Bean をバッチ化してバッチで処理できるようにします。たとえば、一度に 100 件のバッチで処理します。

new QCustomer()
 .status.equalTo(Status.NEW)
 .order().id.asc()
 .findEach(100, batch -> {
   // process the customers in batches of 100 at a time
   // where batch is List<Customer>
   ...
 });

findStream

ストリームとして結果を処理するクエリを実行します。try with resources ブロックを使用して、ストリームが保持するリソースが閉じられたままになっていることを確認します。

try (Stream<Customer> stream =
  new QCustomer()
   .status.equalTo(Status.NEW)
   .order().id.asc()
   .findStream()) {

  stream
    .filter(...)
    .map(..)
    .collect(...);
}

findIterate

QueryIterator として結果を処理するクエリを実行します。try with resources ブロックを使用して、イテレーターが保持するリソースが閉じられたままになっていることを確認します。

try (QueryIterator<Customer> it =
  new QCustomer()
   .status.equalTo(Status.NEW)
   .order().id.asc()
   .findIterate()) {

   while (it.hasNext()) {
     Customer customer = it.next();
     ...
   }
}