Bug 142 : ENHANCEMENT: Add support/api for PagingList and Page ... with fetch ahead and size() support
Priority 
High
Reported Version 
 
Logged By 
Rob
Status 
Fixed
Fixed Version 
2.1.0
Assigned To 
 
Product 
Ebean - core
Duplicate Of 
 
Created 
19/08/2009
Updated 
19/08/2009
Type 
Bug
 
Attachments 
No attachments

Add support for Paging through a result. Build in support for fetching the next page in advance using the new FutureList background fetching and fetching the total size using the new findFutureRowCount feature.

 
Rob 19 Aug 13:11
To reiterate:

Q: Why would you use this rather than the query.firstRow query.maxRows ?

A: It has built in support for fetch ahead (fetching the next page via a background thread once to touch the data in the current page).

It also has built in support for fetching the total row count using findFutureRowCount (so this can be done using a background thread as well).

I am also looking into implementation a ID based paging mechanism which can deal with some of the issues with an limit/offset approach. Deleted/Added rows during paging, performance degradation of limit/offset with large result sets etc.

Rob 19 Aug 13:20
Looking for feedback on this API but currently ...
int pageSize = 10;

PagingList<TOne> pagingList = 
	Ebean.find(TOne.class)
		.where().gt("name", "2")
		.query()
		.findPagingList(10);

		
// get the row count in the background...
// ... otherwise it is fetched on demand
// ... when getRowCount() or getPageCount() 
// ... is called
pagingList.getFutureRowCount();

// use fetch ahead... fetching the next page
// in a background thread when the data in
// the current page is touched
pagingList.setFetchAhead(1);

// get the first page
Page<TOne> page = pagingList.getPage(0);

// get the beans from the page as a list
List<TOne> list = page.getList();

...

Rob 19 Aug 13:22
interface PagingList
public interface PagingList<T> {

	/**
	 * Set the number of pages to fetch ahead using background fetching.
	 * <p>
	 * If set to 0 no fetch ahead is used. If set to 1 then the next page
	 * is fetched in the background as soon as the list is accessed.
	 * </p>
	 */
	public PagingList<T> setFetchAhead(int fetchAhead);
	
	/**
	 * Return the Future for getting the total row count.
	 */
	public Future<Integer> getFutureRowCount();
	
	/**
	 * Return the data in the form of a List.
	 */
	public List<T> getAsList();
	
	/**
	 * Return the page size.
	 */
    public int getPageSize();

    /**
     * Return the total row count waiting if it has not already been 
     * fetched.
     */
    public int getRowCount();
   
    public int getPageCount();
   
    public Page<T> getPage(int i);

}

Rob 19 Aug 13:22
interface Page
public interface Page<T> {

	/**
	 * Return the list of entities for this page.
	 */
	public List<T> getList();

	/**
	 * Return true if there is a next page.
	 */
	public boolean hasNext();

	/**
	 * Return true if there is a previous page.
	 */
	public boolean hasPrev();

	/**
	 * Return the next page.
	 */
	public Page<T> next();

	/**
	 * Return the previous page.
	 */
	public Page<T> prev();
}

Rob 19 Aug 21:46
This is in HEAD

So people can look at it and play with it.

Some thoughts I have for extending this...
- Refresh feature - ie. clear the pages and re-execute the query
- Sort feature - ie. change the orderBy of the query and refresh
- Fetch all - ie. fetch all the rest of the data in one query
- Make is easy to generate "page x of y" and "row x to y of z" strings

woResponse

Upload a file