java – JDBC驱动程序在空的ResultSet上抛出“ResultSet Closed”异常

前端之家收集整理的这篇文章主要介绍了java – JDBC驱动程序在空的ResultSet上抛出“ResultSet Closed”异常前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在sqlite的JDBC驱动程序中有问题.

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

如果我得到一个空的ResultSet(0行),那么当调用getString(1)时,我会看到一个“Closed ResultSet”异常.

没有很多以前的JDBC经验,我的理论(我无法通过JavaDocs为ResultSet确认)就是这样

> getString(1)不适用于空(零行)结果集(按设计或由于错误)
> ResultSet的“open”标志在零行设置为false(再次,通过设计或错误)

我看到这个bug report,但不知道它是否相关.

我的做法是:

以上理论是否正确?
>是bug吗特征? (如果是,有人可以指出文件吗?)
>它是特定于sqlIte的JDBC还是所有JDBC驱动程序中的通用ResultSet?
>做这样的东西的正确方法是什么?

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

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

谢谢!

解决方法

是否空,但执行以下操作总是有问题:
resultSet = statement.executeQuery(sql);
string = resultSet.getString(1); // Epic fail. The cursor isn't set yet.

这不是一个bug.这是documented behaviour.每个decent JDBC tutorial都提到它.您需要使用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,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,birthdate FROM user");
        ResultSet resultSet = statement.executeQuery();
    ) {
        while (resultSet.next()) {
            users.add(new User(
                resultSet.getLong("id"),resultSet.getDate("birthdate")));
        }
    }

    return users;
}

然后在业务/域对象中相应地处理它,例如.

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

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

猜你在找的Java相关文章