アプリケーションにページングを実装しています。このために、クエリを実行して ResultSet を取得します。
ここで、ページング計算のために、この ResultSet 内のレコードの総数を取得したいと考えています。
どうすればこれを入手できますか? 合計行が得られる余分な SQL を実行したくありません。
7 に答える
もう1つのオプションは、クエリのサブクエリ列としてカウント集計を追加することです。データベースが少し賢い場合は、それを1回だけ実行します。お気に入りのデータベースのクエリアナライザを使用して、これを簡単に確認できるはずです。
SELECT id,username,(SELECT COUNT(id) FROM users) FROM users;
通常の方法では、 を実際のデータを表す javabeanにマップしResultSet
ます(例: 、など)。List<Entity>
Entity
User
Product
Order
次に、次のList
ようなメソッドを使用List#size()
して行数を取得できます。
List<Entity> entities = entityDAO.list();
int rows = entities.size();
if (entities.isEmpty()) {
// It is empty!
} else if (entities.size() == 1) {
// It has only one row!
} else {
// It has more than one row!
}
int totalRows = 0;
try {
resultSet.last();
totalRows = resultSet.getRow();
resultSet.beforeFirst();
} catch(Exception ex) {
return 0;
}
return totalRows ;
私が間違っていなければ、ResultSet のデフォルトの動作はすべての行を一度に取得することではないため、オブジェクト自体から、最初に反復せずにクエリから返される行の数を知る方法はありません (したがって、 ) それらすべて。特定のデータベースの特定の JDBC ドライバーでは、異なる動作が発生する場合があります。
最初に COUNT() クエリを実行するとコストがかかりすぎるのはなぜですか? 実際の値を取得するコストと比較して、コストが高すぎることはありません。
コメントからBalusCの回答へ:
[...] 実際には、ページに 10 行のみを表示したいので、コレクション内のすべての行を取得したくないため、ページング計算により、結果セットから 10 行のみを取得できます。このために、結果セットの合計行数が必要です
データベースに約 10 行とテーブルのサイズを要求するだけです。したがって、実際にはデータ ストアに対して 2 つの質問があり、これは 2 つの選択クエリに相当します。Uriが提案したとおりに実行し、「ベスト プラクティス」は気にしないでください。ある日誰かがより良いプラクティスを見つけたとしても、コードを適応させるかどうかを決めることができます。
ページ付けを実装しており、一度に結果セット全体をロードするべきではないため、レコード数を取得するためにリストサイズをカウントする意味はありません。
データベースレベルでROW_NUMを使用して、ページネーションロジックを実装します。画面に表示するのに必要な数のレコードを取得する必要があります。
例:select * from Emp where rownum> =:beginRecord and rownum <=:endRecord
*****ロジックは同じですが、データベースのタイプによって構文が変わる場合があります。列の順序付けを行う必要がある場合は、ネストされたクエリを使用する必要があります。*
count(*)はコストのかかる操作だと思いますが、パーティションバイを好みます。
Eno、Ename、(select count()from emp)as record_count from Emp--Expensive Select Eno、Ename、count()over(partition by eno)as record_countfromEmp--Preferredone。
*****構文によるパーティション分割は、データベースのタイプによって異なる場合があります。*
Oracleデータベースを検討しました。
Fatah ソリューションに加えて、このコードを使用できます。メモリ ポインターであるため、このソリューションにはパフォーマンスの問題がないことにも注意してください。
int totalRows = 0;
if(rowSet.last()) {
totalRows = rowSet.getRow();
}
rowSet.beforeFirst();