Zee*_*han 33 java sql pagination jdbc
我想用JDBC实现分页.我想知道的实际情况是"如何从第1页和第2页的数据库中获得前50个然后下50条记录"
我的查询是Select * from data[数据表包含20,000行]
对于第1页,我得到50条记录,对于第2页,我希望获得接下来的50条记录.如何在JDBC中有效地实现它?
我已经搜索过,发现这rs.absolute(row)是跳过第一页记录的方法,但是在大型结果集上花费了一些时间,我不想承受这么多时间.另外,我不想在查询中使用rownum和limit+ offset,因为这些不适合在查询中使用,我不知道为什么,我仍然不想在查询中使用它.
任何人都可以帮助我如何限制ResultSet分页或JDBC是否有任何方式给我们?
psp*_*psp 26
通过简单地使用JDBC,没有有效的方法.您必须将限制制定为n行,并从第i个项子句直接开始到SQL,以使其高效.根据数据库,这实际上可能非常简单(参见MySQL的LIMIT -keyword),在其他数据库(如Oracle)上,它可能有点棘手(涉及子查询和使用rownum伪列).
请参阅此JDBC分页教程:http: //java.avdiel.com/Tutorials/JDBCPaging.html
Bal*_*usC 20
您应该只查询实际需要在当前页面上显示的数据.不要将整个数据集拖入Java的内存中,然后在那里过滤它.它只会让事情变得不必要地变慢.
如果您实际上很难正确地实现这个和/或为特定数据库计算SQL查询,那么请在这里查看我的答案 .
更新:既然你正在使用Oracle,这里是上述答案的Oracle目标摘录:
在Oracle中,您需要一个子查询with
rownum子句,它应该如下所示:Run Code Online (Sandbox Code Playgroud)private static final String SQL_SUBLIST = "SELECT id, username, job, place FROM" + " (SELECT id, username, job, place FROM contact ORDER BY id)" + " WHERE ROWNUM BETWEEN %d AND %d"; public List<Contact> list(int firstrow, int rowcount) { String sql = String.format(SQL_SUBLIST, firstrow, firstrow + rowcount); // Implement JDBC. return contacts; }
无视Hibernate分页,我们可以使用SQL分页/ JDBC分页
SQL分页
有两种基本方法:
这样做的方法是SQL特定的
对于MySQL /许多其他SQL,可以使用限制和偏移来完成
Postgresql:http://microjet.ath.cx/WebWiki/ResultPaginationWithPostgresql.html
在Oracle中,它使用与处理"Top-N查询"相同的形式,例如谁是5位最高薪员工,这是优化的
select * from ( select a.*, rownum rnum
from ( YOUR_QUERY_GOES_HERE -- including the order by ) a
where rownum <= MAX_ROWS )
where rnum >= MIN_ROWS
Run Code Online (Sandbox Code Playgroud)
JDBC分页
我想到的问题是:当我执行SQL时,如何加载结果?是立即还是应要求?和这个SO线程一样
首先,我们需要了解一些JDBC的基础知识,例如Oracle
每个javadoc:statement.execute()
execute: Returns true if the first object that the query returns is a ResultSet object. Use this method if the query could return one or more ResultSet objects. Retrieve the ResultSet objects returned from the query by repeatedly calling Statement.getResutSet.
Run Code Online (Sandbox Code Playgroud)
我们通过游标访问Resultset中的数据.请注意,此光标与DB的光标不同,而它是最初位于第一行数据之前的指针.
根据请求获取数据.当你执行execute()时,你是第一次获取.
那么,加载了多少数据?它是可配置的.可以使用ResultSet上的java API setFetchSize()方法来控制驱动程序每次从DB获取的行数,以及它一次检索的块大小.
例如,假设总结果为1000.如果获取大小为100,则获取第1行将从DB加载100行,第2行将从本地内存加载到第100行.查询第101行将另外100行加载到内存中.
来自JavaDoc
Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for ResultSet objects genrated by this Statement. If the value specified is zero, then the hint is ignored. The default value is zero.
Run Code Online (Sandbox Code Playgroud)
注意单词"hint" - 它可以通过驱动程序特定的实现来覆盖.
这也是基于SQL开发人员的客户端中的"限制行数为100"的功能.
完成整个解决方案,要滚动结果,需要考虑API中的ResultSet类型和ScrollableCursor
可以从oracle中的这篇文章中找到一个示例实现
它来自Oracle Toplink Developer's Guide Example 112 JDBC Driver Fetch Size
ReadAllQuery query = new ReadAllQuery();
query.setReferenceClass(Employee.class);
query.setSelectionCriteria(new ExpressionBuilder.get("id").greaterThan(100));
// Set the JDBC fetch size
query.setFetchSize(50);
// Configure the query to return results as a ScrollableCursor
query.useScrollableCursor();
// Execute the query
ScrollableCursor cursor = (ScrollableCursor) session.executeQuery(query);
// Iterate over the results
while (cursor.hasNext()) {
System.out.println(cursor.next().toString());
}
cursor.close();
Run Code Online (Sandbox Code Playgroud)
.....................
毕竟,问题沸腾了
哪种分页更好?
注意SQL应该是ORDER by才能在SQL方法中有意义,
否则,可以在下一页中再次显示一些行.
以下是Postgresql关于JDBC驱动程序和其他SO答案的文档中的一些要点
首先,原始查询需要有一个ORDER BY子句才能使寻呼解决方案合理地工作.否则,Oracle为第一页,第二页和第N页返回相同的500行是完全有效的
主要区别在于JDBC方式,在获取期间需要保持连接.例如,这可能不适用于无状态Web应用程序.
对于SQL方式
语法是特定于SQL的,可能不容易维护. 对于JDBC方式
一些进一步阅读
| 归档时间: |
|
| 查看次数: |
79731 次 |
| 最近记录: |