Java JDBC Lazy-Loaded ResultSet - PullRequest
29 голосов
/ 12 июня 2009

Есть ли способ получить ResultSet, который вы получаете при запуске JDBC-запроса, для ленивой загрузки? Я хочу, чтобы каждая строка загружалась так, как я ее запрашиваю, а не заранее.

Ответы [ 5 ]

36 голосов
/ 12 июня 2009

Краткий ответ:

Используйте Statement.setFetchSize(1) перед вызовом executeQuery().

Длинный ответ:

Это зависит очень от того, какой драйвер JDBC вы используете. Возможно, вы захотите взглянуть на эту страницу , которая описывает поведение MySQL, Oracle, SQL Server и DB2.

Основные выносы:

  • Каждая база данных (то есть каждый драйвер JDBC) имеет свое поведение по умолчанию.
  • Некоторые водители будут соблюдать setFetchSize() без каких-либо предостережений, в то время как другим требуется некоторая «помощь».

MySQL - особенно странный случай. См. эту статью . Звучит так, будто вы звоните setFetchSize(Integer.MIN_VALUE), тогда он будет загружать строки по одной, но это не совсем понятно.

Другой пример: вот документация для поведения PostgreSQL. Если автоматическая фиксация включена, ResultSet будет извлекать все строки одновременно, но если она отключена, вы можете использовать setFetchSize(), как и ожидалось.

И последнее, о чем следует помнить: эти настройки драйвера JDBC влияют только на то, что происходит на стороне клиента. Сервер все еще может загрузить весь набор результатов в память, но вы можете контролировать, как клиент загружает результаты.

3 голосов
/ 12 июня 2009

Не могли бы вы добиться этого, установив размер выборки для вашего оператора в 1?

Если вы выбираете только 1 строку за раз, каждая строка не должна загружаться до тех пор, пока вы не вызовете next () в ResultSet.

, например

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
}
0 голосов
/ 21 ноября 2017

Ответ предоставлен здесь .

Цитата:

Драйвер JDBC Presto никогда не буферизует весь набор результатов в памяти. Серверный API будет возвращать не более ~ 1 МБ данных драйверу за запрос. Драйвер не будет запрашивать больше данных с сервера, пока эти данные не будут использованы (вызывая метод next() для ResultSet соответствующее количество раз).

Из-за того, как работает серверный API, размер выборки драйвера игнорируется (согласно спецификации JDBC, это только подсказка).

Докажите, что setFetchSize игнорируется

0 голосов
/ 12 июня 2009

Вы найдете это намного проще, используя hibernate . В основном вам придется свернуть свои собственные, если вы используете jdbc напрямую.

Стратегии извлечения в hibernate легко настраиваются и, скорее всего, предложат варианты производительности, о которых вы даже не знали.

0 голосов
/ 12 июня 2009

Я думаю, что вы хотели бы отложить фактическую загрузку самого ResultSet. Вам нужно будет реализовать это вручную.

...