16

私の Java (JDK6) プロジェクトでは、すべてのデータベース アクセスにSpringJDBCTemplateを使用しています。最近、Spring 2.5 から Spring 3 (RC1) にアップグレードしました。プロジェクトはHibernateEJBのような ORM を使用しません。

大量のレコードを読み取り、内部処理を行う必要がある場合、いくつかの (オーバーロードされた) メソッドがあるようです: query、queryForList、および queryForRowSet

一方を他方の代わりに使用する基準は何ですか? パフォーマンスの違いはありますか? ベストプラクティス?

このトピックに関するさらなる研究のために、いくつかの外部参照を推奨できますか?

4

3 に答える 3

45

リストとしてアクセスする標準的なquery()方法は、他のアプローチではなくメソッドを使用することです。と他のメソッドの主な違いは、結果セットを処理するためにコールバック インターフェイス ( 、、または)queryのいずれかを実装する必要があることです。RowMapperRowCallbackHandlerResultSetExtractor

ARowMapperは、ほとんどの場合、自分が使用しているものです。結果セットの各行がリスト内の 1 つのオブジェクトに対応する場合に使用されます。mapRow行に入るオブジェクトのタイプを入力して返す単一のメソッドを実装するだけで済みます。Spring にはBeanPropertyRowMapper、Bean プロパティ名を列名に一致させることにより、リスト内のオブジェクトを設定できる もあります (注: このクラスは、パフォーマンスではなく便宜上のものです)。

ARowCallbackHandlerは、結果を単なるリスト以上のものにする必要がある場合に便利です。このアプローチを使用している戻りオブジェクトを自分で管理する必要があります。通常、戻り値の型としてマップ構造が必要な場合 (つまり、ツリー テーブルのグループ化されたデータの場合、または主キーに基づいてカスタム キャッシュを作成する場合)、これを使用しています。

AResultSetExtractorは、結果の繰り返しを制御する場合に使用されます。extractDataへの呼び出しの戻り値となる単一のメソッドを実装しqueryます。他のコールバック インターフェイスのいずれかを使用して構築するのがより複雑なカスタム データ構造を構築する必要がある場合にのみ、これを使用していることに気づきます。

これらのqueryForList()メソッドは、これらのコールバック メソッドを実装する必要がないという点で価値があります。queryForList を使用する方法は 2 つあります。1 つ目は、データベースから 1 つの列 (文字列のリストなど) のみをクエリする場合、クラスを引数として受け取るメソッドのバージョンを使用して、それらのクラスのオブジェクトのみのリストを自動的に提供できます。 .

の他の実装を呼び出すと、queryForList()各エントリが各列のマップであるリストが返されます。これは、コールバック メソッドを記述する費用を節約できるという点で優れていますが、このデータ構造を扱うのは非常に扱いにくいものです。マップの値は type であるため、多くのキャストを行っていることに気付くでしょうObject

私は実際にqueryForRowSet野生で使用されている方法を見たことがありません. これにより、クエリの結果全体がCachedRowSet、Spring SqlRowSet によってラップされたオブジェクトにロードされます。このオブジェクトを使用することの大きな欠点は、アプリケーションの他のレイヤーに渡す場合、SqlRowSetそれらのレイヤーをデータ アクセスの実装に結合することになるということです。

で述べた場合を除いて、これらの呼び出し間で大きなパフォーマンスの違いは見られないはずBeanPropertyRowMapperです。ResultSetExtractor大規模な結果セットの複雑な操作を行っている場合は、特定のケースに最適化された を作成することで、パフォーマンスが向上する可能性があります。

詳細については、 Spring JDBC のドキュメントと、私が言及したクラスの JavaDoc を参照してください。また、Spring Framework に関するいくつかの書籍を参照することもできます。少し時代遅れですが、Spring Frameworkを使用した Java 開発には、JDBC フレームワークの操作に関する非常に優れたセクションがあります。何よりも、各メソッドでコードを書いてみて、何が最適かを確認してください。

于 2009-11-07T20:33:47.500 に答える
3

上記の優れた回答への小さな追加: queryForInt、queryForLong、queryForMap、queryForObject などの追加のメソッドは、単純なクエリを実行していて、単一の行が必要な場合に適したオプションのように見えることがあります。

ただし、0 行または 1 行を取得できる場合は、通常、queryForList メソッドの方が簡単です。それ以外の場合は、IncorrectResultSizeDataAccessException をキャッチする必要があります。私はそれを難し​​い方法で学びました。

于 2009-11-11T22:41:51.243 に答える
3

あなたは素晴らしいジェネリックの世界にいるので、本当にやりたいことは、オブジェクトや個々のオブジェクトに対してSimpleJdbcTemplateそのquery()メソッドを使用したり使用したりすることです。これは単純に、 にあるものよりもさらに使いやすいという理由からです。ListsqueryForObject()JdbcTemplate

于 2009-11-02T12:12:09.290 に答える