JDBC クエリを実行して取得した ResultSet を遅延ロードする方法はありますか? 事前にではなく、要求したときに各行をロードしたい。
5 に答える
簡潔な答え:
Statement.setFetchSize(1)
呼び出す前に使用しexecuteQuery()
ます。
長い答え:
これは、使用している JDBC ドライバーに大きく依存します。MySQL、Oracle、SQL Server、および DB2 の動作について説明しているこのページをご覧になることをお勧めします。
主なポイント:
- 各データベース (つまり、各 JDBC ドライバー) には、独自のデフォルトの動作があります。
setFetchSize()
一部のドライバーは警告なしで尊重しますが、他のドライバーは何らかの「助け」を必要とします。
MySQL は特に奇妙なケースです。この記事を参照してください。setFetchSize(Integer.MIN_VALUE)
を呼び出すと、行が 1 つずつダウンロードされるように聞こえますが、完全に明確ではありません。
別の例: PostgreSQL の動作に関するドキュメントは次のとおりです。自動コミットがオンの場合、ResultSet は一度にすべての行をフェッチしますが、オフの場合はsetFetchSize()
期待どおりに使用できます。
最後に 1 つ注意してください。これらの JDBC ドライバーの設定は、クライアント側での動作にのみ影響します。サーバーは引き続き結果セット全体をメモリにロードする場合がありますが、クライアントが結果をダウンロードする方法を制御できます。
Statement のフェッチ サイズを 1 に設定することで、これを実現できませんでしたか?
一度に 1 行のみをフェッチする場合、ResultSet で next() を呼び出すまで、各行はロードされません。
例えば
Statement statement = connection.createStatement();
statement.setFetchSize(1);
ResultSet resultSet = statement.executeQuery("SELECT .....");
while (resultSet.next())
{
// process results. each call to next() should fetch the next row
}
あなたがしたいことは、ResultSet自体の実際のロードを延期することだと思います。手動で実装する必要があります。
hibernateを使用すると、これがずっと簡単になります。jdbc を直接使用している場合は、基本的に自分で作成する必要があります。
Hibernate でのフェッチ戦略は高度に構成可能であり、ほとんどの場合、あなたが気付いていなかったパフォーマンス オプションを提供します。