JDBC 结果集总行数

发布于 2024-09-05 15:01:29 字数 110 浏览 13 评论 0原文

我正在我的应用程序中实现分页。为此,我运行查询并获取结果集。
现在我想获取此 ResultSet 中的记录总数以进行分页计算。
我怎样才能得到这个?我不想执行额外的 SQL,这会给我总行数。

I am implementing Paging in my application. For this I run a query and get a ResultSet.
Now I want to get total number of records in this ResultSet for my paging calculation.
How can I get this ? I don't want to execute extra SQL which gives me total rows.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

一腔孤↑勇 2024-09-12 15:01:29

另一种选择是将计数聚合添加为查询中的子查询列。如果您的数据库有点智能,它只会执行一次。您应该能够使用您最喜欢的数据库中的查询分析器轻松检查这一点。

SELECT id,username,(SELECT COUNT(id) FROM users) FROM users;

Another option is to add the count aggregation as a sub queried column in your query. If your database is just a little bit smart, it will only execute that once. You should be able to check this easily using the query analyzer in your favorite database.

SELECT id,username,(SELECT COUNT(id) FROM users) FROM users;
作业与我同在 2024-09-12 15:01:29

通常的做法是将 ResultSet 映射到 List,其中 Entity 是代表实际结果的 javabean数据,例如 UserProductOrder 等。

然后,您可以使用 List 方法,例如 List#size() 获取行数。

List<Entity> entities = entityDAO.list();
int rows = entities.size();

if (entities.isEmpty()) {
    // It is empty!
} else if (entities.size() == 1) {
    // It has only one row!
} else {
    // It has more than one row!
}

The normal practice is to map the ResultSet to a List<Entity> where Entity is a javabean representing the actual data, e.g. User, Product, Order, etc.

Then, you can just use List methods like List#size() to obtain the rowcount.

List<Entity> entities = entityDAO.list();
int rows = entities.size();

if (entities.isEmpty()) {
    // It is empty!
} else if (entities.size() == 1) {
    // It has only one row!
} else {
    // It has more than one row!
}
鸵鸟症 2024-09-12 15:01:29
int totalRows = 0;
    try    {
        resultSet.last();
        totalRows = resultSet.getRow();
        resultSet.beforeFirst();
    } catch(Exception ex)  {
               return 0;
          }
    return totalRows ;
int totalRows = 0;
    try    {
        resultSet.last();
        totalRows = resultSet.getRow();
        resultSet.beforeFirst();
    } catch(Exception ex)  {
               return 0;
          }
    return totalRows ;
贪恋 2024-09-12 15:01:29

如果我没有记错的话,ResultSet 的默认行为不是一次获取所有行,因此无法从对象本身知道在不首先迭代的情况下从查询中返回多少行(从而检索)全部。对于特定数据库的特定 JDBC 驱动程序,您可能会得到不同的行为。

请问为什么先运行 COUNT() 查询成本太高?与检索实际值的成本相比,它应该不会太贵。

If I'm not mistaken, the default behavior for a ResultSet is not to obtain all the rows at once, so there is no way to know from the object itself how many rows would be returned from the query without first iterating (and thus retrieving) all of them. You might get different behavior with specific JDBC drivers for specific databases.

May I ask why it is too costly for you to run a COUNT() query first ? Compared to the cost of retrieving the actual values, it shouldn't be too expensive.

以往的大感动 2024-09-12 15:01:29

从对 BalusC 答案的评论:

[...] 实际上,我不想获取集合中的所有行,因为我只想在页面上显示 10 行,因此我的分页计算可以帮助我从结果集中仅获取 10 行。为此,我需要结果集中的总行数

您只想向数据库询问大约 10 行表的大小。因此,您的数据存储实际上有两 (2) 个问题,这相当于两 (2) 个选择查询。按照 Uri 建议进行操作,不要关心“最佳实践”。如果有一天有人提出了更好的实践,您仍然可以决定是否调整您的代码。

From a comment to BalusC's answer:

[...] Actually i dont want to get all rows in a collection because i want to display only 10 rows on page thus my paging calculation helps me to get only 10 rows from resultset. For this i need total no of rows in resultset

You want nothing but asking the database for about 10 rows and the size of the table. so you actually have two (2) questions to your data store which is equal to two (2) select queries. Do it as Uri suggested and don't care about 'best practice'. If one day someone comes around with a better practice you still can decide whether to adapt your code or not.

请止步禁区 2024-09-12 15:01:29

计算列表大小来获取记录数是没有意义的,因为我们正在实现分页并且不应该一次加载整个结果集。

我在数据库级别使用 ROW_NUM 来实现分页逻辑。我们需要获取尽可能多的记录以将其显示在屏幕上。

示例: select * from Emp where rownum>=:beginRecord 和 rownum<=:endRecord

***** 逻辑将相同,但语法可能会根据数据库类型而变化。如果我们需要对任何列进行排序,则需要使用嵌套查询。*

我相信, count(*) 是昂贵的操作,而我更喜欢分区。

选择 Eno、Ename ,(从 emp 中选择 count())作为 Emp 中的 record_count -- 昂贵
从 Emp 中选择 Eno、Ename、count(
)(按 eno 分区)作为 record_count - 首选。

***** 按语法分区可能会根据数据库类型而变化。 *

我考虑过Oracle数据库。

There is no point in counting List size to get record count, as we are implementing pagination and SHOULD NOT load entire resultset at a time.

I use ROW_NUM at database level to implement pagination logic. We need to get the as many records as we need to show it on the screen.

Example: select * from Emp where rownum>=:beginRecord and rownum<=:endRecord

***** Logic will be the same but syntax may change depending up on the type of the database. Need to use nested query if we need to do order by of any column.*

I believe, count(*) is expensive operation, rather i prefer partition by.

Select Eno, Ename , (select count() from emp) as record_count from Emp -- Expensive
Select Eno, Ename , count(
) over (partition by eno) as record_count from Emp -- Preferred one.

***** Partition by syntax may change depending up on the type of the database.*

I have considered Oracle database.

自由如风 2024-09-12 15:01:29

除了 Fathah 解决方案之外,您还可以使用此代码,还要注意,因为它是内存指针,所以此解决方案没有性能问题:

int totalRows = 0;
if(rowSet.last()) {
   totalRows = rowSet.getRow();
}
rowSet.beforeFirst();

in addition to Fathah solution you can use this code, also note that because its a memory pointer this solution has no performance issues:

int totalRows = 0;
if(rowSet.last()) {
   totalRows = rowSet.getRow();
}
rowSet.beforeFirst();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文