Disclaimer: This blog post about pagination and pagination JDBC posted by me.
Without considering Hibernate pagination, we can use pagination / pagination / JDBC
pagination <
There are two main approaches:
- working on a private result set (a new query for each page)
- works with a full set of results
The way to do this is SQL specific
For MySQL / many other SQL, this can be done using constraint and offset
Postgresql: http://microjet.ath.cx/WebWiki/ResultPaginationWithPostgresql.html
In Oracle, it uses the same form as for processing a βTop-N request,β for example. who are the 5 highest paid employees who are optimized
select * from ( select a.*, rownum rnum from ( YOUR_QUERY_GOES_HERE
Here is a detailed description of ROW-NUM
Similar SO stream
JDBC Breakdown
The question is: when I execute SQL, how is the result loaded? Immediately or upon request? same as this SO stream
First we need to understand some of the basics of JDBC, like from Oracle
Per 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.
We access the data in the Resultset using the cursor. Note that this cursor is different from what the DB has, while it is a pointer originally positioned before the first row of data.
Data is displayed on request. and when you execute execute (), you select for the first time.
Then how much data is downloaded? It is customizable. You can use the java API setFetchSize () method for ResultSet to control how many rows are retrieved from the DB in time by the driver, how large blocks it retrieves immediately.
For example, suppose the final result is 1000. If the sample size is 100, the first row will load 100 rows from the database, and 2 β the 100th row will be loaded from local memory. To request the 101st line, another 100 lines will be loaded into memory.
From 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.
Pay attention to the word "hint" - it can be redefined by the specific driver implementation.
It is also that "Limit Rows to 100" functions as a client, such as an SQL developer.
Completing the entire solution, to scroll through the results, you need to consider the ResultSet and ScrollableCursor types in the API
You can find an example implementation from this post in oracle
which from the book Oracle Toplink Developer's Guide Example 112 JDBC Driver Sample Size
ReadAllQuery query = new ReadAllQuery(); query.setReferenceClass(Employee.class); query.setSelectionCriteria(new ExpressionBuilder.get("id").greaterThan(100));
.....................
After all, questions boil up
What is the best way to do pagination?
Note that SQL must be ORDER in order to make sense in the SQL approach,
Otherwise, you can show several lines on the next page.
Below are some points from the Postgresql documentation for the JDBC driver and other SO answers
Initially, the original query must have an ORDER BY clause to make the swap decision reasonable. Otherwise, it would be perfectly fair if Oracle returns the same 500 rows for the first page, second page and Nth page
The main difference is the JDBC method, connection is required during extraction. For example, this may not be suitable for an unnamed web application.
For SQL path
The SQL syntax is specific and can be difficult to maintain. For the JDBC path
- The connection to the server must be connected to the V3 protocol. This is the default for (and only supported) server versions 7.4 and later.
- The connection should not be in automatic mode. The backend closes the cursors at the end of transactions, so in autocommit mode, the backend will close the cursor before anything can be extracted from it.
- A statement must be created using the ResultSet type ResultSet.TYPE_FORWARD_ONLY. This is the default value, so the code will not need to be rewritten to take advantage of this, but it also means that you cannot scroll back or jump into the ResultSet otherwise.
- The given query should be one operator, and not several statements strung together with semicolons.
Some extra reading
This post is about tuning performance with optical sample size.