我正试图找到一种方法如何强制jaybird在ResultSet中进行“分页”。假设我们有一些持久的sql查询(它在15秒内返回例如5000行)。但是,获取前50个(随机)行只需要几分之一秒。只要我们不向查询添加order by子句,服务器就会快速返回第一行,这些行可以立即显示在客户端应用程序中。这是火焰客户端的默认行为。
我尝试通过设置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();
}
我尝试实现与flamerobin客户端一样的想法 - 将数据快速加载到表中(仅当我们需要它们时 - 向下滚动到表中)。我们开发了应用程序,它是两层ERP系统(DB服务器firebird,netbeans平台上的客户端)的客户端。我们编写了一些数据库组件,它们使用与“interbase Delphi组件”相同的原理填充JXTable数据。上面的代码是简化的,在组件代码中我们将前100行加载到JTable表模型,当用户向下滚动时我们加载另外100行等。但是我注意到前100行的加载时间与以下相同我们将所有行加载到数据集。那是代码
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循环将在从DB服务器获取前50行后立即启动。所以我想在获取前50行之后启动while循环(就好像我设置了stmt.setMaxRows(50)),但我希望机会让结果集打开并按需获取另一行。
答案 0 :(得分:0)
使用defaultHoldable
通常会完全符合您的预期:它将以指定大小的批量获取行(Firebird 3可以决定在批量过大时返回较少)。
但是,由于您在连接字符串中指定了HOLD_CURSORS_OVER_COMMIT
,因此结果集为CLOSE_CURSORS_AT_COMMIT
,并且可保留的结果集在返回之前完全缓存在客户端。
您需要为此特定语句将可保持性设置为defaultHoldable
,或者 - 如果对所有语句执行此操作 - 只需从连接字符串中删除CODE:
int min=1;
int max=10;
int y=0;
Random rand = new Random();
for(int count=0;count<1;count++){
int randomNum = rand.nextInt((max - min) + 1) + min;
arr[count] = randomNum;
}
System.out.println(arr[0]);//for checking
System.out.println(randomNum);//for checking
。