Получить несколько записей одновременно

0

На этот вопрос может быть уже дан ответ, но я не могу найти хороший, я пытаюсь прочитать данные из одной базы данных и выполнить некоторую операцию, и моя исходная база данных очень огромна, как 100 миллионов записей или 100 ГБ таблицы, поэтому я попробовал метод ниже, чтобы извлекать несколько записей за раз, чтобы я не получал исключение памяти, но то, что я получаю, - это только максимальные записи того, что я установил для setMaxRows(), например, если я установил 100, я получаю только 100 и я тестирую это против базы данных mysql.

Вот мой код Java:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCTest {

    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "root", "root");
             conn.setAutoCommit(false);
             Statement stmt = conn.createStatement();

             stmt.setMaxRows(100);
             ResultSet rs = stmt.executeQuery("select * from mydatabase.posthistory");
             int i=0;
             for (;;) {
                 System.out.println("Reading the set from: "+i);
                    while (rs.next()) {
                        i++;
                        System.out.println(i);
                    }
                    if ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1)) {
                        System.out.println("End of reading.");
                        break;
                    }           
                }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            conn.close();
        }
    }

}

Может кто-то сказать, что я делаю неправильно здесь. Любая помощь или предложения будут замечательными. И я использую драйвер mysql jsbc версии 5.1.22. если я запускаю его нормально, то java пытается довести все данные до данных, которые бросают мне ошибку,

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
  • 0
    Я бы предложил попробовать JPA-фреймворк, такой как Hibernate или Eclispelink, и использовать функциональность курсора. Это создаст поток результатов.
Теги:

2 ответа

0
Лучший ответ

Для использования базы данных Mysql

    stmt = connection.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                        java.sql.ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE);

Для других баз данных

stmt.setFetchSize(1000);

Это не приведет к извлечению всей базы данных в объект ResultSet.

  • 0
    если я сохраню stmt.setFetchSize (Integer.MIN_VALUE); сколько записей я получу за раз?
  • 0
    Я не уверен, сколько записей он загружает за один раз в MySQL, но он не загружает все данные в объект набора результатов. Сохраняет указатель и загружает данные в последовательности. Это решило вашу проблему?
Показать ещё 1 комментарий
0

Используйте Statement.setFetchSize для управления количеством строк, которые буферизуются. Значение по умолчанию - 0, которое может буферировать весь результат, в зависимости от драйвера.

Обратите внимание, что опция MySQL JDBC useCursorFetch должна быть включена для работы setFetchSize. См. Примечания к реализации:

Другой альтернативой является использование потоковой передачи на основе курсора для получения заданного количества строк каждый раз. Это можно сделать, установив для свойства connectionCursorFetch значение true, а затем вызвав setFetchSize (int), когда int будет желательным количеством строк, которые будут извлекаться каждый раз:

conn = DriverManager.getConnection(
    "jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t"
);

stmt = conn.createStatement();
stmt.setFetchSize(100);
rs = stmt.executeQuery("SELECT * FROM your_table_here");

Statement.setMaxRows просто ограничивает количество возвращаемых строк и заставляет лишние строки отбрасываться, как вы заметили.

  • 0
    поэтому, если я установлю setFetchSize, он будет выполнять запрос, но будет одновременно получать только 100 записей в оперативную память? Моя проблема заключается в том, что если java перенесет все записи в оперативную память, будет выдано сообщение об ошибке «Исключение в потоке« main » java.lang.OutOfMemoryError: пространство кучи Java "
  • 0
    Это верно.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню