当前位置:  开发笔记 > 编程语言 > 正文

JDBC驱动程序在空ResultSet上抛出"ResultSet Closed"异常

如何解决《JDBC驱动程序在空ResultSet上抛出"ResultSetClosed"异常》经验,为你挑选了3个好方法。

我在SQLite的JDBC驱动程序中遇到问题.

我正在使用SELECT语句执行查询.

如果我得到一个空ResultSet(0行),那么我看到调用时抛出的"Closed ResultSet"异常getString(1).

如果没有先前的JDBC经验,我的理论(我无法通过JavaDocs确认ResultSet)就是这样

getString(1) 不适用于空(零行)结果集(按设计或由于错误)

ResultSet'open"标志设置false为零行(再次,设计或错误)

我看到了这个错误报告,但不确定它是否相关.

我的问题是:

    上述理论是否正确?

    这是一个错误吗?特征?(如果有的话,有人可以指向文件吗?)

    它是特定于SQLIte的JDBC还是ResultSet所有JDBC驱动程序中的泛型?

    这样做的正确方法是什么?

对于#4,我的解决方案是在之后使用isFirst()call executeQuery()来检查结果集中是否有任何行.这是最佳做法吗?

(我也可以简单地选择一个计数insetad,因为我不需要一个结果集,只有零非零标志,但我想知道正确的事情,如果我关心选择的结果)

谢谢!



1> BalusC..:

是否清空,但执行以下操作始终有问题:

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

这不是一个错误.这是记录在案的行为.每个体面的JDBC教程都会提到它.next()在能够访问任何数据之前,您需要使用ResultSet的光标.

如果您真的对是否存在所谓的唯一行感兴趣,那么只需检查结果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 list() throws SQLException {
    List users = new ArrayList();

    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 users = userDAO.list();

if (!users.isEmpty()) {
    int count = users.size();
    // ...
}
else {
    // Help, no users?
}



2> Doug Currie..:
while (rs.next()) {
 // process the row
}



3> Phil Ross..:

从ResultSet的JavaDocs :

ResultSet对象维护指向其当前数据行的游标.最初,光标位于第一行之前.下一个方法将光标移动到下一行,因为当ResultSet对象中没有更多行时它返回false,它可以在while循环中用于迭代结果集.

在尝试读取任何数据之前ResultSet,您需要将行放置在一行,例如通过调用next().如果调用next()return,false则结果集为空.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有