14

私の目標は、実際にはデータベースのすべてのデータを XML ファイルにダンプすることです。データベースはそれほど大きくなく、約 300MB です。問題は、(JVM で) 256MB のメモリ制限しかないことです。したがって、明らかに、すべてをメモリに読み込むことはできません。

この問題は、iBatis (はい、myBatis ではなく iBatis を意味します) を使用して、incremented を使用してgetList(... int skip, int max)複数回呼び出すことで解決できskipました。これでメモリの問題は解決しますが、速度には感銘を受けません。変数名は、メソッドがフードの下で行うことは、結果セット全体をスキップしてから指定されたレコードを読み取ることであることを示唆しています。これは私にはかなり冗長に思えます (メソッドがそうしていると言っているわけではありません。変数名に基づいて推測しているだけです)。

さて、アプリケーションの次のバージョンのために myBatis 3 に切り替えました。私の質問は: myBatis でチャンクごとに大量のデータを処理するより良い方法はありますか? myBatis で最初の N レコードを処理し、結果セットの接続を開いたまま呼び出し元に返す方法はありますか「スキップ」?

4

5 に答える 5

16

myBatis は結果をストリーミングできます。必要なのは、カスタムの結果ハンドラーです。これにより、各行を個別に取得して XML ファイルに書き込むことができます。全体的なスキームは次のようになります。

session.select(
    "mappedStatementThatFindsYourObjects",
    parametersForStatement,
    resultHandler);

ここで、resultHandler は ResultHandler インターフェースを実装するクラスのインスタンスです。このインターフェイスにはメソッドが 1 つだけありますhandleResult。このメソッドは、ResultContext オブジェクトを提供します。このコンテキストから、現在読み取られている行を取得して、それに対して何かを行うことができます。

handleResult(ResultContext context) {
  Object result = context.getResultObject();
  doSomething(result);
}
于 2011-11-02T07:06:28.880 に答える
7

いいえ、mybatis にはまだ結果をストリーミングする完全な機能がありません。

編集 1: ネストされた結果マッピングが必要ない場合は、カスタム結果ハンドラーを実装して結果をストリーミングできます。MyBatis の現在リリースされているバージョン。(3.1.1) 現在の制限は、複雑な結果マッピングを行う必要がある場合です。NestedResultSetHandler はカスタム結果ハンドラーを許可しません。修正が利用可能で、現在 3.2 を対象としているようです。Issue 577を参照してください。

要約すると、MyBatis を使用して大きな結果セットをストリーミングするには、必要になります。

  1. 独自の ResultSetHandler を実装します
  2. フェッチ サイズを増やします。(ギヨーム・ペローが以下に記したように)
  3. ネストされた結果マップについては、Issue 577で説明されている修正を使用してください。この修正により、大規模な結果セットに関する一部のメモリの問題も解決されます。
于 2011-07-11T18:51:57.807 に答える
2

handleResult は、クエリが取得するのと同じ数のレコードを受け取ります。一時停止はありません。

処理するレコードが多すぎる場合は、sqlSessionFactory.getSession().getConnection() を使用しました。次に、通常の JDBC として、Statement を取得し、Resultset を取得して、レコードを 1 つずつ処理します。セッションを閉じることを忘れないでください。

于 2014-07-05T02:08:16.163 に答える