web-dev-qa-db-ja.com

JDBC結果セットと行セットどちらをいつ選択するか?

したがって、いくつかの相対的な違いを認識しています。つまり、ResultSetにはデータベースへの「オープン接続」がありますが、RowSetは「切断された」方法で機能します。

しかし、それは私が理解していることとほぼ同じです(間違っているかもしれません:)

私の質問はこれです-どのような状況で一方が他方よりも好ましいのですか?それぞれの長所/短所は何ですか?

  • 特に「読み取り専用」クエリに対して切断モードで動作するRowSetは、並行性の高いシステムでパフォーマンスが向上すると私は感じています。あれは正しいですか?その場合、読み取り専用クエリでは、RowSetがResultSetよりも常に好ましいと言っても安全ですか?

  • RowSetを正しく反復しても、SQL例外はスローされませんが、それは利点ですか?もう1つは、RowSetがシリアライズ可能であることです。しかし、私の懸念は主にパフォーマンスの観点から何を選択するのでしょうか?

  • しかし、それは読み取り/書き込みクエリにとっても重要ですか? ResultSetをDBに同期して戻すことはできますか? (それが可能かどうかはわかりません(可能性があり、十分に思い出したりグーグルで検索したりすることはできません:)生のJDBCでしばらく経ちました...

何か案は?明らかなように、私の知識にはいくつかの欠落しているギャップがあります:)

私が尋ねる理由は、Spring-JdbcのResultSetExtractorインターフェイスを実装するか、一部のデータを処理するときにSqlRowSetを返すかを選択したいからです。この質問は、コインを投げる以外に、いつ何を選ぶべきかを決める方法に興味を持っただけです:)

17
PhD

RowSet

RowSet はほとんどの場合正しい選択であり、より完全な機能を備えており、リストしたすべての利点があるだけでなく、データの場合に常に使用する切断されたCachedRowSetなどの特別な目的のための特別な実装がありますはメモリに収まるので、接続をできるだけ早くプールに解放して再利用できます。

ResultSetは決して公的契約の一部であってはなりません。

接続されたResultSet/Rowsetは、メソッドまたは最悪の場合、それらを作成したオブジェクトからエスケープしてはなりません。少なくともRowSetを使用すると、接続を切断でき、クライアントは実装について気にする必要がありません。 * JDBC固有の機能またはコントラクトと相互作用または依存するResultSet固有のライブラリコードを記述している場合を除きます。

クエリの結果を転送するだけの場合は、JDBC固有のクラスをパブリックコントラクトの一部にする必要があります。

理想的には、RowSet/ResultSetコンテンツをタイプセーフなドメインオブジェクトにマテリアライズして渡します。

ほとんどの場合、コードをJDBC apiに直接結合するのではなく、ドメインオブジェクトのList/Setをマテリアライズして操作および操作する必要があります。

Visitorパターンを使用したタイプセーフドメインインスタンスの生成を処理するために、ResultSetMapper<T>クラスを採用した最新の方法が数多く存在します。これは、慣用的な方法であるためです。

9
user177800

私はJRの答えに同意しません。 RowSetは多くの場合良い選択ですが、いつものように、最良の答えは状況とニーズによって異なります。すべてにRowSetを使用しても機能不全のコードは生成されませんが、ResultSetよりもパフォーマンスが低下する可能性があります(一般的なJdbcRowSet実装はResultSetのラッパーです)。

JavaBeanを必要とするモジュラーコードで結果オブジェクトを使用する必要がある場合、RowSetsはJava Beansの最小要件を満たします。

マルチスレッド/サーバーアプリのコードを開発している場合は、すべてのJava Beanは変更可能であるため、スレッドセーフではないという譲歩を受け入れる必要があります。その結果、ResultsetもRowSetもスレッドではありません。安全。

データベースクエリを消費し、それらをアプリケーションの残りの部分で使用するためにJavaデータモデルオブジェクトに変換するコードを記述している場合、RowSetはResultsetよりもパフォーマンスが低い可能性があります。

私が書いている多くのコードでは、JDBCデータベースクエリを受け取ったときに、結果セットを使用して、取得した行をデータモデルオブジェクトのリストにすぐに処理していました。結果セットは、変換を実行するメソッド呼び出しにも耐えられません。私の意見では、これは良いことです...結果セット(したがってRowSet)は多くのリソースを消費し、できるだけ早くgcで利用できるようにしたいからです。

このモードでは、RowSetはもちろん、Resultsetの新しい機能も必要ありません。セットを1回繰り返して、結果行のリストを生成するだけです。

RowSetが非常に望ましい状況があります。 RowSetはシリアル化可能で、表面上は「軽量」であるため、切断されたCachedRowSet(たとえば)は、特にデータをその場で更新可能にする場合に、場所間でデータベースクエリ結果を送信するためのかなり効率的なメカニズムを表します。もちろん、オブジェクトのリストをシリアル化して送信することもできます。

24
scottb