Итератор Java поддерживается ResultSet

Я соглашаюсь с compacity решения для переключателя, но IMO Вы угон переключателя здесь.
цель переключателя состоит в том, чтобы иметь отличающийся обработка в зависимости от значения.
, Если бы необходимо было объяснить алгоритм в псевдокоде, Вы использовали бы если потому что, семантически, вот что это значит: , если whatever_error делают это ...
Поэтому, если Вы не намереваетесь когда-нибудь изменить свой код для имения определенного кода для каждой ошибки, я использовал бы если .

31
задан dimo414 4 November 2013 в 14:47
поделиться

8 ответов

Это плохая идея. Этот подход требует, чтобы соединение было открыто все время, пока не будет прочитана последняя строка, а за пределами уровня DAO вы никогда не знаете, когда это произойдет, и вы также, кажется, оставляете набор результатов открытым и рискуете утечками ресурсов и сбоями приложения в случае время ожидания соединения истекло. Вы не хотите этого.

Обычная практика JDBC заключается в том, что вы приобретаете Connection , Statement и ResultSet в кратчайшей возможной области. Обычной практикой также является отображение нескольких строк в List или, может быть, в Map и угадайте, что у них действительно есть Iterator .

public List<Data> list() throws SQLException {
    List<Data> list = new ArrayList<Data>();

    try (
        Connection connection = database.getConnection();
        Statement statement = connection.createStatement("SELECT id, name, value FROM data");
        ResultSet resultSet = statement.executeQuery();
    ) {
        while (resultSet.next()) {
            list.add(map(resultSet));
        }
    }

    return list;
}

private Data map(ResultSet resultSet) throws SQLException {
    Data data = new Data(); 
    data.setId(resultSet.getLong("id"));
    data.setName(resultSet.getString("name"));
    data.setValue(resultSet.getInteger("value"));
    return data;
}

И используйте его, как показано ниже:

List<Data> list = dataDAO.list(); 
int count = list.size(); // Easy as that.
Iterator<Data> iterator = list.iterator(); // There is your Iterator.

Не передавайте дорогостоящие ресурсы БД за пределы уровня DAO, как вы изначально хотели. Для более простых примеров обычных практик JDBC и шаблона DAO вы можете найти эту статью полезной.

37
ответ дан 27 November 2019 в 21:31
поделиться

Похоже, вы застряли между предоставлением неэффективной реализации hasNext или выдача исключения о том, что вы не поддерживаете операцию.

К сожалению, бывают случаи, когда вы реализуете интерфейс, и вам не нужны все члены.

-1
ответ дан 27 November 2019 в 21:31
поделиться

Ожидаете ли вы, что большая часть данных в вашем наборе результатов действительно будет использоваться? Если это так, предварительно закешируйте его. Это довольно просто, например, Spring

  List<Map<String,Object>> rows = jdbcTemplate.queryForList(sql);
  return rows.iterator();

Отрегулируйте по своему вкусу.

0
ответ дан 27 November 2019 в 21:31
поделиться

entity.next возвращает false, если строк больше нет, поэтому вы можете просто получить это возвращаемое значение и установить переменную-член, чтобы отслеживать статус для hasNext ().

Но для того, чтобы это работало, вам также потребуется какой-то метод инициализации, который считывает первую сущность и кэширует ее в классе. Затем при вызове next вам нужно будет вернуть ранее кэшированное значение и кэшировать следующее значение и т. Д.

1
ответ дан 27 November 2019 в 21:31
поделиться

Вы можете попробовать следующее:

public class A implements Iterator {
    private ResultSet entities;
    private Entity nextEntity;
    ...
    public Object next() {
        Entity tempEntity;
        if ( !nextEntity ) {
            entities.next();
            tempEntity = new Entity( entities.getString...etc....)
        } else {
            tempEntity = nextEntity;
        }

        entities.next();
        nextEntity = new Entity( entities.getString...ext....)

        return tempEntity;
    }

    public boolean hasNext() {
        return nextEntity ? true : false;
    }
}

Этот код кэширует следующую сущность, а hasNext () возвращает истину, если кешированная сущность действительна, иначе возвращает ложь.

2
ответ дан 27 November 2019 в 21:31
поделиться

ResultSet имеет метод isLast (), который может удовлетворить ваши потребности. В JavaDoc говорится, что это довольно дорого, хотя и требует предварительного чтения. Есть большая вероятность, что он кэширует прогнозируемое значение, как и другие предложения.

5
ответ дан 27 November 2019 в 21:31
поделиться

Вы можете выйти из этого рассола, выполнив предварительный просмотр в hasNext () и вспомнив, что вы выполнили поиск, чтобы предотвратить потребление слишком большого количества записей, например:

public class A implements Iterator{
    private ResultSet entities;
    private boolean didNext = false;
    private boolean hasNext = false;
    ...
    public Object next(){
        if (!didNext) {
            entities.next();
        }
        didNext = false;
        return new Entity(entities.getString...etc....)
    }

    public boolean hasNext(){
        if (!didNext) {
            hasNext = entities.next();
            didNext = true;
        }
        return hasNext;
    }
    ...
}
39
ответ дан 27 November 2019 в 21:31
поделиться

Там это пара вещей, которые вы можете сделать в зависимости от того, что вы хотите от своего класса A.

2
ответ дан 27 November 2019 в 21:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: