Драйвер JDBC бросает “ResultSet Закрытое” исключение на пустой ResultSet

Я думаю, что Вы подвели итог его вполне хорошо в Вашем собственном ответе.

В процессе UTF-8-ing(?) от вплотную Вы могли бы также хотеть удостовериться, что сам Java использует UTF-8. Используйте-Dfile.encoding=utf-8 в качестве параметра к JVM (может быть настроен в catalina.bat).

9
задан BalusC 6 July 2015 в 17:09
поделиться

3 ответа

Пусто или нет, но выполнение следующих действий всегда неверно :

resultSet = statement.executeQuery(sql);
string = resultSet.getString(1); // Epic fail. The cursor isn't set yet.

Это не ошибка. Это задокументированное поведение . Это упоминается в каждом приличном руководстве по JDBC . Вам необходимо установить курсор ResultSet с помощью next () , прежде чем вы сможете получить доступ к любым данным.

Если вас действительно интересует, существует ли предположительно уникальная строка или нет, тогда просто проверьте результат next () . Например, в фиктивном классе UserDAO :

public boolean exist(String username, String password) throws SQLException {
    boolean exist = false;

    try (
        Connection connection = database.getConnection();
        PreparedStatement statement = connection.prepareStatement("SELECT id FROM user WHERE username = ? AND password = MD5(?)");
    ) {
        statement.setString(1, username);
        statement.setString(2, password);

        try (ResultSet resultSet = statement.executeQuery()) {
            exist = resultSet.next();
        }
    }

    return exist;
}

Если вы действительно ожидаете только ноль или одну строку, то просто выполните что-то вроде:

public User find(String username, String password) throws SQLException {
    User user = null;

    try (
        Connection connection = database.getConnection();
        PreparedStatement statement = connection.prepareStatement("SELECT id, username, email, birthdate FROM user WHERE username = ? AND password = MD5(?)");
    ) {
        statement.setString(1, username);
        statement.setString(2, password);

        try (resultSet = statement.executeQuery()) {
            if (resultSet.next()) {
                user = new User(
                    resultSet.getLong("id"),
                    resultSet.getString("username"),
                    resultSet.getString("email"),
                    resultSet.getDate("birthdate")); 
            }
        }
    }

    return user;
}

, а затем просто обработайте это соответствующим образом в бизнес-объекте / доменном объекте, например

User user = userDAO.find(username, password);

if (user != null) {
    // Login?
}
else {
    // Show error?
}

Если вы действительно ожидаете только ноль или много строк, затем просто выполните что-то вроде:

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

    try (
        Connection connection = database.getConnection();
        PreparedStatement statement = connection.prepareStatement("SELECT id, username, email, birthdate FROM user");
        ResultSet resultSet = statement.executeQuery();
    ) {
        while (resultSet.next()) {
            users.add(new User(
                resultSet.getLong("id"),
                resultSet.getString("username"),
                resultSet.getString("email"),
                resultSet.getDate("birthdate")));
        }
    }

    return users;
}

, а затем просто обработайте это соответствующим образом в бизнес-объекте / доменном объекте, например

List<User> users = userDAO.list();

if (!users.isEmpty()) {
    int count = users.size();
    // ...
}
else {
    // Help, no users?
}
17
ответ дан 4 December 2019 в 07:35
поделиться

Из JavaDocs для ResultSet :

Объект ResultSet поддерживает курсор указывая на текущую строку данных. Изначально курсор установлен перед первым рядом. Следующий способ перемещает курсор в следующую строку и потому что он возвращает false, когда есть больше нет строк в ResultSet объект, его можно использовать в цикле while для итерации по набору результатов.

Вам необходимо разместить ResultSet в строке, например, вызвав вызов next () , прежде чем пытаться прочитать какие-либо данные. Если вызов next () возвращает false , то набор результатов пуст.

5
ответ дан 4 December 2019 в 07:35
поделиться
while (rs.next()) {
 // process the row
}
6
ответ дан 4 December 2019 в 07:35
поделиться
Другие вопросы по тегам:

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