【发布时间】:2016-02-19 17:11:31
【问题描述】:
我正在尝试找到一种方法来强制 jaybird 在 ResultSet 中进行“分页”。假设我们有一些持久的 sql 查询(例如,它在 15 秒内返回 5000 行)。但是,获取前 50 行(随机)只需要几分之一秒。只要我们不在查询中添加 order by 子句,服务器就会快速返回第一行,这些行可以立即显示在客户端应用程序中。这是flarerobin客户端的默认行为。
我尝试通过设置以下代码中的 Statement 参数来模拟这种行为,但没有成功。有没有办法强制 jaybird 不将所有行加载到 ResultSet?我想方法 stmt.setFetchSize(50) 有这个目的,但它可能是错误的。使用的 Jaybird 版本是 2.2.7,使用的 Firebird 版本是 2.5.4。谢谢你的建议。
String user = "user";
String pass = "pass";
Connection conn = DriverManager.getConnection(s, user, pass);
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(50);
stmt.setFetchDirection(ResultSet.FETCH_FORWARD);
ResultSet rs = null;
String sql = "select * from TABLE"; //long lasting select
boolean ok = stmt.execute(sql);
if (ok) {
rs = stmt.getResultSet();
while (rs.next()) {
//do something
}
}
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
我尝试实现与flarerobin 客户端相同的想法——将数据动态加载到表中(仅当我们需要它们时——在表中向下滚动)。我们开发的应用程序是两层 ERP 系统的客户端(DB 服务器 firebird,netbeans 平台上的客户端)。我们编写了一些数据库组件,这些组件用数据填充 JXTable,就像过去的“interbase Delphi 组件”一样。上面的代码是简化的,在组件代码中,我们将前 100 行加载到 JTable 表模型中,当用户向下滚动时,我们加载另外 100 行等。但是我注意到前 100 行的加载时间与 if我们将所有行加载到数据集中。就是代码
boolean ok = stmt.execute(sql);
if (ok) {
rs = stmt.getResultSet();
int rows = 0;
while (rs.next() rows < 100) {
//do something
rows++;
}
}
实际上与第一块源代码的时间相同。似乎, stmt.execute(sql) 命令等待,直到所有选择行都从服务器返回。但是我设置我想获得 50 行块,所以我认为 while 循环将在从数据库服务器获得前 50 行后立即开始。所以我想在获取前 50 行后开始 while 循环(就像我设置了 stmt.setMaxRows(50)),但我希望有机会让结果集打开并按需获取另一行。
【问题讨论】:
-
设置获取大小将指示 jaybird 以 50 为一组获取行(尽管某些 Firebird 版本可能会选择返回较小的数字)。但是,它不会限制返回的行数。您的代码仍在获取所有行,只是每批 50 行。您要达到什么目的?如果您最初只想返回 50 次,则不应调用 next() 超过 50 次,或使用
setMaxRows。 -
问题被附加(完成)作为对 Mark Rotteveel 评论的回应。
-
您是否在连接字符串中使用
defaultResultSetHoldable=true? -
我的连接地址是 jdbc:firebirdsql:server:/path/db.fdb?encoding=UTF8&dialect=3&defaultHoldable
-
如果您使用
defaultResultSetHoldable,则会立即检索整个结果集。
标签: java jdbc pagination firebird jaybird