Как получить JDBC ResultSet как ArrayList?

Я делаю запрос для извлечения большого количества идентификаторов (целых чисел). Вместо того, чтобы повторять миллионы раз через ResultSet и копировать все один за другим в ArrayList, есть ли способ просто получить все как ArrayList?

Я понимаю, что ResultSet должен быть итерирован, потому что основная реализация может быть кешированием, но в моей ситуации мне просто нужны все идентификаторы сразу. Я знаю, что я могу установить FetchSize на большое число, но потом мне все равно нужно получать идентификаторы один за другим.

Уточнение: причина, по которой я хочу это сделать, - это производительность. Профилирование показывает мне, что выполнение ResultSet.next(), ResultSet.getInt() и ArrayList.add() в миллионы раз занимает довольно много времени. Я полагаю, что база данных (я использую H2, написанную на Java), вероятно, имеет массив или список где-то в памяти, поэтому я ищу способ скопировать его мне напрямую, а не через интерфейс повторения ResultSet.

Ответы

Ответ 1

Используя библиотеку Apache DbUtils, вы можете легко вернуть ResultSet в виде списка карт.

public List query(String query) {
    List result = null;
    try {
        QueryRunner qrun = new QueryRunner();
        result = (List) qrun.query(connection, query, new MapListHandler());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return result;
}

Ответ 2

Поместите код в метод. Это очень просто вызвать методы...

Сверху моей головы:

public static List<Integer> readInts(
     PreparedStatement statement
) throws SQLException {
     ResultSet results = statement.executeQuery();
     try {
         assert results.getMetaData().getColumnCount() == 1;

         List<Integer> ints = new ArrayList<Integer>();
         while (results.next()) {
             ints.add(Integer.valueOf(results.getInt(1)));
         }
         return ints;
     } finally {
         results.close();
     }
}

Затем просто назовите его как:

List<Integer> ids = readInts(myStatemnet);

Готово.

Ответ 3

Если ваша проблема плохой производительности, настройте оператор перед его выполнением с помощью

java.sql.Statement.setFetchSize(int)

Эксперимент с 100, 1000, 10000,.. Это позволит избежать ненужных закруглений, что может быть причиной медленности, о которой вы говорили.

Кроме того, ArrayList.add() может быть медленным, если он должен многократно изменять размер внутреннего массива, поскольку он создает новый массив и копирует туда все данные. Вместо этого попробуйте LinkedList.