私のJava(JDK6)プロジェクトは、すべてのデータベースアクセスに Spring および JDBCTemplate を使用します。最近Spring2.5からSpring3(RC1)にアップグレードしました。 )。プロジェクトは Hibernate や [〜#〜] ejb [〜#〜] のようなORMを使用しません。
大量のレコードを読み取り、それらを使用して内部処理を行う必要がある場合、query、queryForList、queryForRowSetのいくつかの(オーバーロードされた)メソッドがあるようです。
どちらか一方を使用するための基準は何ですか?パフォーマンスに違いはありますか?ベストプラクティス?
このトピックに関するさらなる調査のために、いくつかの外部参照をお勧めできますか?
リストとしてアクセスする標準的な方法は、他のアプローチではなく、query()
メソッドを使用することです。 query
と他のメソッドの主な違いは、コールバックインターフェイスの1つ(RowMapper
、RowCallbackHandler
、またはResultSetExtractor
のいずれか)を実装する必要があることです。 )結果セットを処理します。
RowMapper
は、ほとんどの場合に使用しているものです。結果セットの各行がリスト内の1つのオブジェクトに対応する場合に使用されます。行に入るオブジェクトのタイプを入力して返す単一のメソッドmapRow
を実装するだけで済みます。 SpringにはBeanPropertyRowMapper
もあり、Beanのプロパティ名を列名と照合することでリスト内のオブジェクトにデータを入力できます(注:このクラスはパフォーマンスではなく便宜上のものです)。
RowCallbackHandler
は、結果を単なるリスト以上のものにする必要がある場合に役立ちます。このアプローチを使用している場合は、リターンオブジェクトを自分で管理する必要があります。私は通常、戻り値の型としてマップ構造が必要な場合(つまり、ツリーテーブルのグループ化されたデータの場合、または主キーに基づいてカスタムキャッシュを作成している場合)にこれを使用します。
ResultSetExtractor
は、結果の反復を制御する場合に使用されます。 extractData
への呼び出しの戻り値となる単一のメソッドquery
を実装します。他のコールバックインターフェイスのいずれかを使用して構築するのがより複雑なカスタムデータ構造を構築する必要がある場合にのみ、これを使用していることに気付きます。
queryForList()
メソッドは、これらのコールバックメソッドを実装する必要がないという点で価値があります。 queryForListを使用する方法は2つあります。 1つ目は、データベースから1つの列(文字列のリストなど)のみをクエリする場合、引数としてクラスを受け取るメソッドのバージョンを使用して、それらのクラスのオブジェクトのみのリストを自動的に提供できることです。 。
queryForList()
の他の実装を呼び出すと、各エントリが各列のマップであるリストが返されます。これは、コールバックメソッドを作成する費用を節約できるという点で優れていますが、このデータ構造の処理は非常に扱いにくいものです。マップの値はObject
型であるため、多くのキャストを行っていることに気付くでしょう。
私は実際に実際に使用されているqueryForRowSet
メソッドを見たことがありません。これにより、クエリの結果全体がSpringSqlRowSetによってラップされたCachedRowSet
オブジェクトに読み込まれます。このオブジェクトを使用することには大きな欠点があります。アプリケーションの他のレイヤーにSqlRowSet
を渡す場合、それらのレイヤーをデータアクセスの実装に結合することになります。
BeanPropertyRowMapper
で述べた場合を除いて、これらの呼び出しの間に大きなパフォーマンスの違いは見られないはずです。大規模な結果セットの複雑な操作を行っている場合は、特定のケースに最適化されたResultSetExtractor
を作成することで、パフォーマンスを向上させることができる場合があります。
詳細を知りたい場合は、 Spring JDBCドキュメント および 私が言及したクラスのJavaDoc を参照してください。 SpringFrameworkに関する本のいくつかを見ることができます。少し古いですが Spring Frameworkを使用したJava開発 JDBCフレームワークの操作に関する非常に優れたセクションがあります。何よりも、各メソッドでコードを書いてみて、何が最適かを確認してください。
あなたは素晴らしいジェネリックスの土地にいるので、本当にやりたいことは SimpleJdbcTemplate
を使用し、そのquery()
メソッドをLists
に使用することです。オブジェクトの数と個々のオブジェクトのqueryForObject()
。これは、JdbcTemplate
にあるものよりも使いやすいという理由だけです。
上記の優れた回答への小さな追加:queryForInt、queryForLong、queryForMap、queryForObjectなどの追加のメソッドは、単純なクエリを実行していて単一の行を期待している場合、良いオプションのように見えることがあります。
ただし、0行または1行を取り戻すことができる場合は、queryForListメソッドの方が一般的に簡単です。そうでない場合は、IncorrectResultSizeDataAccessExceptionをキャッチする必要があります。私はそれを難しい方法で学びました。