获取 Java 结果集中的行数

Posted

技术标签:

【中文标题】获取 Java 结果集中的行数【英文标题】:Getting the count of rows in a Java resultset 【发布时间】:2011-03-04 10:07:29 【问题描述】:

有没有人知道一种更好的方法来获取从 mysql 数据库返回的 Java 结果集中的行数?返回的结果集不会是从数据库中读取的总行数,所以我认为我不能使用 SQL 的 COUNT 聚合函数。

public static int getResultSetRowCount(ResultSet resultSet) 
    int size = 0;
    try 
        resultSet.last();
        size = resultSet.getRow();
        resultSet.beforeFirst();
    
    catch(Exception ex) 
        return 0;
    
    return size;

【问题讨论】:

调用 resultSet.last() 将导致结果集实际上遍历所有记录 - 所以它显然是低效的。即使您还不需要它,它也会强制将所有数据缓存到内存中。您为什么说“他返回的结果集不会是从数据库中读取的总行数”? @RonK:你认为它为什么会一直迭代?我在文档中找不到类似的内容。 @Ronk:从数据库表读取的数据将只是表数据的子集,而不是表中的所有数据。不过,我对“全面迭代”感到好奇。 @Adeel Ansari:我不是 100% 确定,我反编译了 Oracle 的结果集,发现在调用 'last()' 方法的流程中, 'cacheAllRows()' 方法被调用,并且该方法以“while(resultSet.next())”开头。我认为 MySQL 驱动程序不会有更好的事情要做。 @Mr Morgan:正如下面的一些答案所述 - 如果你有一个获取数据的 SQL,你可以有相同的返回 COUNT() - 我看不出为什么它不能工作。 【参考方案1】:

更好的答案是在您成功将 ResultSet 加载到对象或集合中之前忘记行数。您可以使用这些选项中的任何一个来保留行数。

在尽可能窄的方法范围内关闭 ResultSet(以及所有 SQL 资源,如 Connection 和 Statement)非常重要。这意味着不将 ResultSet 传递出持久层。最好使用 Collection size() 调用来获取行数。

停止思考数据库,开始思考对象。 Java 是一种面向对象的语言。

【讨论】:

(+1) 当然,你是对的。 count() 对我来说非常好,但在这种情况下不是。我们通常这样做是为了实现分页。 我发现自己想知道行数,以便创建一个大小合适的ArrayList。我的意思是,摊销成本可以忽略不计,但如果我能在第一时间做对,为什么不做对呢? :-) 现代 Java 版本中的 try-with-resources 是确保数据库对象在完成后关闭的好方法。【参考方案2】:

也可以通过以下方式获取resultSet中的总记录数:

statement = connect.createStatement();
resultSet = statement.executeQuery(sqlStatement);
resultSet.last();
int count = resultSet.getRow();
System.out.println(count);

count 是您的结果集返回的总行数。 ;)

【讨论】:

只有在结果集是可滚动的情况下才有效,它会遍历所有记录,效率不高。【参考方案3】:

这是我对这个问题的解决方案(因为我主要希望返回的记录数来构建数组或类似的东西):改用 Vector<T> 之类的集合。

public Vector<T> getRecords()
   Vector<T> records = new Vector<T>();
   init_conn_and_stmt_and_rs();

   try 
      rs = stmt.executeQuery("SELECT * FROM `table` WHERE `something` = 0");
      while(rs.next())
         // Load the Vector here.
      
    catch (SQLException e) 
      e.printStackTrace();
   finally
      close_rs_and_stmt_and_conn();
   
   return records;

干净简单,不是吗?适用于返回的任何大小的记录集(无需事先知道大小)并使所有List 方法可用。

这已经为我服务了一段时间,但如果有人发现其中的缺陷,请告诉我。一直想让我的练习变得更好,你知道的。

【讨论】:

【参考方案4】:

如果您使用的是 Java 6,则可以使用 JDBC4ResultSet 类,该类具有 getUpdateCount 方法,该方法返回受 SQL 语句影响的行数,即使对于 Select 语句也是如此。

参见下面的示例代码:

PreparedStatement ps = con.prepareStatement("select * from any_table ...");
JDBC4ResultSet rs = (JDBC4ResultSet)ps.executeQuery();
int rowNumber = rs.getUpdateCount();

希望对你有所帮助!

【讨论】:

这实际上不适用于 MySQL。即使有一行,我得到的只是-1。【参考方案5】:

在创建实际的SELECT 之前,您始终可以使用具有相同条件的SELECT COUNT()

【讨论】:

@Mr Morgan:这对我来说完全没问题。实际上,我们做类似的事情来实现分页。但是,我们会在第二个查询中询问特定的行数。但是在您的情况下,duffymo 非常正确。当您已经查询数据库时,为什么不将其加载到列表或其他东西中。 我目前正在按照 duffymo 的想法查看二维数组列表。之前,我需要结果集的行数来计算二维字符串数组的大小。 或者当我试图从系统架构中访问表元数据时,我可以使用一个有两个字段的类,列名,列类型,然后创建这个类的数组列表。这里的要点是避免遍历结果集,集合中的此类就足够了。【参考方案6】:

你可以执行

SELECT FOUND_ROWS()

在执行 SELECT 语句后立即查找行数。

【讨论】:

这是一个有趣的答案。您能否提供可以完成此操作的 java 代码?

以上是关于获取 Java 结果集中的行数的主要内容,如果未能解决你的问题,请参考以下文章

可以通过查询结果获取结果集行数吗?

《网站数据分析》8.8 使用TOP子句限制结果集

如何获取 JDBC 中的行数?

Java Hibernate 计数行

sql server查询结果集复制出来的行数和在SSMS上的行数不一致

mysql获取表中数据行数