2

データベースからオブジェクトのロードを取得するメソッドがあります。これは。を返しますIterable

今のところ、データベースから結果セットをロードし、データベースからオブジェクトを構築し、コレクションにそれらのオブジェクトを入力しています。

明らかに、この方法を使用してロードできるデータの量と、Bad Things Happenが不足した場合は、メモリに制約があります。

一度にすべてを取得するのではなく、データベースからデータをチャンク化するように実装を変更し、結果のオブジェクトをインターフェイスを介してクライアントに公開したいと思いIterableます。私のデータベースドライバーは自分のビットを実行できるので、私の最初の考えは、Iterableこれを実行するカスタム実装です。

これは良いアプローチですか?それは、ランタイムまたはライブラリですでにサポートされている可能性があるものとして私を驚かせます-ORMソリューションを含まないでください。

4

2 に答える 2

3

個人的に私が考えることができる最も簡単な解決策は、のIterator周りに薄いラッパーとしてを実装することResultSetです。これにはいくつかの利点があります。

  • 再現可能なSQLステートメントを提供する必要はありません(たとえば、ソートされていない結果をストリーミングできます)
  • 繰り返し可能な読み取りに依存する必要はありません。これはコストがかかる可能性があります
  • JDBCドライバーが優れている場合は、そのストリーミング結果機能を使用できます(警告:一部のJDBCドライバーは、反復を開始するとすぐに常に完全な結果を取得します!)
  • 再起動を実装する必要はありませんIteratorIterable.iterator()2回呼び出すことができるため、これは複雑になります)。
  • 以前に返されたデータを「記憶」しないということは、メモリ要件をかなり低く抑えることができることを意味します

また、いくつかの欠点があります。

  • 実装はJDBCリソースをバインドするため、事実上外部リソースになりますIterator。何らかの方法で「閉じる」必要があり、使用が難しくなります。
  • ハングアラウンドがIterator長くなると、JDBCConnectionハングアラウンドします。これは、他の場所で必要になる可能性があります(完了するまで、プールに戻すことはできませんIterator)。

別の方法は、必要に応じてデータの一部を遅延復元するList(または)を実装することです。Collectionこれは使い勝手が良いかもしれませんが、構築するのはかなり複雑です(正しく!)。また、メモリの制約が重要な場合は、以前に復元されたオブジェクトを破棄するメカニズムを追加する必要があります。

于 2011-10-28T08:45:19.647 に答える
1

Joachimが提案したアプローチをアプリケーションの1つに実装しました。DestroyableIteratorメソッドを含むインターフェースを実装しました。ラッパー実装destroy()の場合は、を閉じました。(一部のライブラリはこのインターフェイスを提供していますが、3行のインターフェイス定義のためにライブラリの依存関係を導入する意味がわかりませんでした。)ResultSetResultSet

また、イテレータとメソッドを介してそれらを伝播するために、をキャッチSQLExceptionして(チェックされていない)Springに変換しました。DataAccessExceptionnext()hasNext()

リソースの保持に関するポイントは有効です。私はを使用してアプリケーションコードを制御していたので、ライブを長時間DestroyableIterator保持しないようにするためのさまざまなタイムアウトメカニズムがありました。ResultSet

于 2011-10-28T08:53:54.543 に答える