我在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,因为我不需要一个结果集,只有零非零标志,但我想知道正确的事情,如果我关心选择的结果)
谢谢!
是否清空,但执行以下操作始终有问题:
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 Listlist() 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; }
然后在业务/域对象中相应地处理它,例如
Listusers = userDAO.list(); if (!users.isEmpty()) { int count = users.size(); // ... } else { // Help, no users? }
while (rs.next()) { // process the row }
从ResultSet的JavaDocs :
ResultSet对象维护指向其当前数据行的游标.最初,光标位于第一行之前.下一个方法将光标移动到下一行,因为当ResultSet对象中没有更多行时它返回false,它可以在while循环中用于迭代结果集.
在尝试读取任何数据之前ResultSet
,您需要将行放置在一行,例如通过调用next()
.如果调用next()
return,false
则结果集为空.