Как избежать циклического выбора записей из SQL таблицы?

При попытке получить все записи из столбца PostgreSQL базы данных через JDBC в виде списка, с какой-то причиной, начиная с второго индекса цикла for, столбцы остаются незаполненными. Пожалуйста, помогите выявить возможную причину и предложить решения. Вот фрагмент моего кода: 

private List<String> getValues(ResultSet set, int index) throws SQLException {
        List<String> list = new ArrayList<>();
        while (set.next()) {
            list.add(set.getString(index));
        }

        return list;
    }

    private @Nullable List<Column> getColumns(ResultSet data) {
        try {
            for (int i = 1; i <= data.getMetaData().getColumnCount(); i++) {
                System.out.println(getValues(data, i));
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        return null;
    }
[3, 2, 1, 4]
[]
[]
  • 1 декабря 2023 г. 15:09
Ответы на вопрос 2
Ваша проблема связана с тем, что после первого вызова метода getValues() курсор ResultSet перемещается в конец и нет больше элементов для перебора. По этой причине второй и последующие вызовы метода не приводят к любому действию, потому что для них результат уже исчерпан.

Чтобы исправить это, вы можете создать новый экземпляр ResultSet для каждого вызова getValues(). Но так как это может быть неэффективно или просто невозможно в некоторых случаях, лучшим решением будет сразу собирать все столбцы во время первого прохода.

Вот как это могло бы выглядеть:

```java
private List<List<String>> getColumns(ResultSet data) {
    List<List<String>> allColumns = new ArrayList<>();
    try {
        while (data.next()) {
            for (int i = 1; i <= data.getMetaData().getColumnCount(); i++) {
                if (allColumns.size() < i)
                    allColumns.add(new ArrayList<>());
                allColumns.get(i - 1).add(data.getString(i));
            }
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    }

    return allColumns;
}
```

В данном коде мы создаем внешний цикл для обхода строк, а внутренний цикл идет по столбцам. Таким образом, мы собираем все данные за одну итерацию.

Помимо этого, не забудьте закрыть ResultSet и Statement по окончании работы с ними, так как они занимают ценные ресурсы.
ResultSet содержит курсор, указывающий на активную строку данных. Когда вы вызываете метод next, курсор переходит на следующую строку. Иными словами, в методе getValues вы перемещаетесь по строкам, а не по столбцам. 
Похожие вопросы