我正在我的应用程序中实现分页。为此,我运行一个查询并获得一个 ResultSet。
现在,我想获取此 ResultSet 中的记录总数以进行分页计算。
我怎样才能得到这个?我不想执行额外的 SQL,这给了我总行数。
7 回答
另一种选择是将计数聚合添加为查询中的子查询列。如果您的数据库有点智能,它只会执行一次。您应该能够使用您喜欢的数据库中的查询分析器轻松检查这一点。
SELECT id,username,(SELECT COUNT(id) FROM users) FROM users;
通常的做法是将 映射ResultSet
到一个表示实际数据的 javabean 的位置,例如List<Entity>
, ,等。Entity
User
Product
Order
然后,您可以使用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!
}
int totalRows = 0;
try {
resultSet.last();
totalRows = resultSet.getRow();
resultSet.beforeFirst();
} catch(Exception ex) {
return 0;
}
return totalRows ;
如果我没记错的话,ResultSet 的默认行为不是一次获取所有行,因此没有办法从对象本身知道在没有第一次迭代的情况下会从查询返回多少行(因此检索) 他们都是。对于特定数据库的特定 JDBC 驱动程序,您可能会获得不同的行为。
请问为什么先运行 COUNT() 查询成本太高?与检索实际值的成本相比,它应该不会太贵。
计算列表大小来获取记录计数是没有意义的,因为我们正在实现分页并且不应该一次加载整个结果集。
我在数据库级别使用 ROW_NUM 来实现分页逻辑。我们需要获取尽可能多的记录,以便在屏幕上显示它。
示例:select * from Emp where rownum>=:beginRecord and rownum<=:endRecord
***** 逻辑将是相同的,但语法可能会根据数据库的类型而改变。如果我们需要对任何列进行排序,则需要使用嵌套查询。*
我相信, count(*) 是昂贵的操作,而我更喜欢分区。
Select Eno, Ename, (select count( ) from emp) as record_count from Emp -- 昂贵 Select Eno, Ename, count( ) over (partition by eno) as record_count from Emp -- 首选。
***** 语法分区可能会根据数据库的类型而改变。*
我考虑过Oracle数据库。
除了 Fathah 解决方案,您还可以使用此代码,还请注意,由于它是一个内存指针,因此此解决方案没有性能问题:
int totalRows = 0;
if(rowSet.last()) {
totalRows = rowSet.getRow();
}
rowSet.beforeFirst();