首页 > 解决方案 > JDBC ResultSet 是否支持分页?

问题描述

JDBC ResultSet 是否支持分页?或者我应该通过缓存结果集在我的服务中实现内部分页。我寻找这种解决方案的原因是 - 我不允许更改表结构。如果允许,我可以有一个自动增量列,然后使用该列上的子句和限制来获取数据。

标签: mysqljdbcresultset

解决方案


但是, AResultSet不会进行分页 - 取决于数据库系统和驱动程序 - 结果可能会分批获取。也就是说,当结果集需要更多行时,它会向服务器请求fetchSize行。

这通常发生在next()被调用并且结果集没有可用的行时(尽管某些实现甚至可能更早地这样做作为性能优化)。

但是,默认情况下,MySQL 连接器/J 驱动程序将在执行时获取内存中的所有行。如结果集下的JDBC API 实施说明中所述

默认情况下,ResultSet 被完全检索并存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于 MySQL 网络协议的设计,更容易实现。如果您正在使用具有大量行或大值的 ResultSet,并且无法在 JVM 中为所需的内存分配堆空间,您可以告诉驱动程序一次将结果流回一行。

Statement要启用此功能,请按以下方式创建实例:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
              java.sql.ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE); 

只进、只读结果集与 fetch 大小的组合Integer.MIN_VALUE用作驱动程序逐行流式传输结果集的信号。在此之后,将逐行检索使用该语句创建的任何结果集。

[..但请阅读警告..]

另一种选择是每次使用基于游标的流来检索一组行。这可以通过将连接属性设置useCursorFetch为 true,然后调用setFetchSize(int) 每次int要获取的所需行数来完成:

conn = DriverManager.getConnection("jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t");
stmt = conn.createStatement();
stmt.setFetchSize(100);
rs = stmt.executeQuery("SELECT * FROM your_table_here");

推荐阅读