我在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? }