如何使用 JDBC 检查结果集是否有一行或多行?
7 回答
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
boolean isMoreThanOneRow = rs.first() && rs.next();
你没有问这个,但你可能需要它:
boolean isEmpty = ! rs.first();
通常,我们不需要行数,因为我们使用 WHILE 循环而不是 FOR 循环来迭代结果集:
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) {
// retrieve and print the values for the current row
int i = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
System.out.println("ROW = " + i + " " + s + " " + f);
}
但是,在某些情况下,您可能希望对结果进行窗口化,并且您需要提前将记录计数显示给用户,例如Row 1 to 10 of 100
. 您可以使用 first 进行单独的查询SELECT COUNT(*)
,以获取记录计数,但请注意,该计数只是近似值,因为可以在执行两个查询所需的时间之间添加或删除行。
ResultSet 概览中的示例
有很多选择,由于你没有提供更多的上下文,剩下的就是猜测。我的答案按复杂性和性能升序排序。
- 只需运行
select count(1) FROM ...
并获得答案。您必须运行另一个实际选择并返回数据的查询。 - 迭代
rs.next()
并计数,直到您满意为止。然后,如果您仍然需要实际数据重新运行相同的查询。 - 如果您的驱动程序支持向后迭代,请执行
rs.next()
几次,然后使用rs.previous()
.
为此,您不需要 JDBC。通常的习惯用法是将所有结果收集到一个集合中,并利用集合方法,例如List#size()
.
List<Item> items = itemDAO.list();
if (items.isEmpty()) {
// It is empty!
if (items.size() == 1) {
// It has only one row!
} else {
// It has more than one row!
}
该list()
方法看起来像这样的地方:
public List<Item> list() throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Item> items = new ArrayList<Item>();
try {
connection = database.getConnection();
statement = connection.createStatement();
resultSet = statement.executeQuery(SQL_LIST);
while (resultSet.next()) {
Item item = new Item();
item.setId(resultSet.getLong("id"));
item.setName(resultSet.getString("name"));
// ...
items.add(item);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return items;
}
我的简单建议:获取第一个结果行,然后尝试获取下一个结果行。如果尝试成功,则您有不止一排。
如果有不止一行并且您想要处理该数据,则需要缓存第一行中的内容,或者使用可滚动的结果集,以便您可以在查看结果之前返回顶部。
您还可以通过SELECT COUNT(*)
对查询的其余部分执行 a 来直接向 SQL 询问此信息;结果将是 0、1 或更多,具体取决于查询的其余部分将返回多少行。这很容易实现,但涉及对数据库的两个查询,假设您接下来要读取和处理实际查询。
如果要确保恰好有一行,可以确保第一行是最后一行:
ResultSet rs = stmt.executeQuery("SELECT a FROM Table1 WHERE b=10");
if (rs.isBeforeFirst() && rs.next() && rs.isFirst() && rs.isLast()) {
// Logic for where there's exactly 1 row
Long valA = rs.getLong("a");
// ...
}
else {
// More that one row or 0 rows returned.
// ..
}
此实现允许您检查查询结果是否为空,代价是复制一些行。
ResultSet result = stmt.executeQuery("SELECT * FROM Table");
if(result.next()) {
// Duplicate the code which should be pasted inside while
System.out.println(result.getInt(1));
System.out.println(result.getString(2));
while(result.next()){
System.out.println(result.getInt(1));
System.out.println(result.getString(2));
}
}else{
System.out.println("Query result is empty");
}
缺点:
- 在这个实现中,部分代码将被复制。
- 您无法知道结果中有多少行。
ResultSetMetaData
使用类获取行数。
从您的代码中,您可以创建ResultSetMetaData
如下:
ResultSetMetaData rsmd = resultSet.getMetaData(); //get ResultSetMetaData
rsmd.getColumnCount(); // get row count from resultsetmetadata