An example illustrates how to implement web paging in Java

  • 2020-04-01 04:16:41
  • OfStack

Paging problem is a very common problem, almost all developers will encounter, not here to discuss how to paging, explain the principle of paging under the Web. The first is to query to get a result set (which is the result of querying the database). If there are too many results to display all the data at once, some data (like 20) will be displayed in a paging manner. Because of Http's statelessness, each submission is treated as a new request, and even if it is a page change, the last result has no effect on the next.

Here are three ways to achieve pagination, I don't know if there is any other!
1. Fetch all the data of the query result each time, and then display the specified record according to the page number.
2. Take only one page of data from the page and display it.
3. Taking a certain number of pages of data is a compromise between the two.

The other thing to note here is whether the data is in the request or session, which is discussed here

1. It is not usually placed in session, because it takes up a lot of memory, so it should be placed in request.
Advantage: the implementation is relatively simple, the query speed is relatively fast.
Disadvantages: occupies the memory some more, the network transfers the data many.
This approach is appropriate for queries with less data. There are people who put data in session so that they don't have to requery it when they change pages, but this is extremely bad and highly recommended.

2. Definitely not in session, because there is no sense in session.
Advantages: less memory usage.
Disadvantage: cumbersome, you have to get the total number of query results first, because you don't know how many pages there are until you know how many records there are. Also, to construct a paging query statement, it is not the same for different databases.

3. This situation is definitely in the session, otherwise why do I take several pages ah, this implementation is to reduce the number of database queries, for example, I keep records of 1 to 10, then when the page change if between 1 to 10 can be directly from the session. If I go to page 11, I can reset the cache to 11
20 pages of data (or 5 to 15 pages of data), which requires 10 changes before one database query operation.
Advantages: relatively small footprint, improved average query speed.
Cons: more complex to implement, potentially dirty data, you need to define your own cache collection. If the amount of data being queried is large, consider this approach.

The following design takes only one page of data at a time and resets the total number of queries each time to get its own implementation, which is a more common paging implementation.

Here is an interface:


package treeroot.util;
import java.util.List;

public interface Pageable
{
  
  public List getResult();
  
  public int getCount();
  
  public int getPageSize();
  
  public int getCurrentPage();
  
  public int getPages();
  
  public final static int DEFAULT_PAGESIZE=20;

}

This interface is very simple, including a list of results and some pagination of the necessary information, here are a few points to note:
1. The implementation of this interface represents a page of data of a certain query, which is irrelevant to the last query
2. The implementation of this interface should be read-only, that is, not modifiable.
The getPages() method is redundant, but it is still provided here.

Here is an abstract implementation:


package treeroot.util;
import java.util.List;

public abstract class AbstractPage implements Pageable
{
  private int currentPage;
  private int pageSize;
  private int pages; 
  
  protected int count;
  protected List result;

  
  public AbstractPage(int currentPage){
    this(currentPage,Pageable.DEFAULT_PAGESIZE);
  }

  
  public AbstractPage(int currentPage,int pageSize) {
    this.currentPage=currentPage;
    this.pageSize=pageSize;
  }

  protected void checkPage(int currentPage) throws PageException{
    if((currentPage<1)||(currentPage>this.getPages()))
       throw new PageException(" Page out of scope : Total number of pages for "+this.getPages()+" , the current page is "+currentPage);
  }
  
  abstract protected void init() throws PageException;
  
  public List getResult()
  {
    return result;
  }
 
  public int getCount()
  {
    return count;
  }

  public int getPageSize()
  {
    return pageSize;
  }

  public int getCurrentPage()
  {
    return currentPage; 
  }
 
  public int getPages()
  {
    if(pages==0) this.pages=(count+pageSize-1)/pageSize;
    return pages;
  }
}

This abstract class implements all the methods in the interface, but defines an abstract method init() that must be implemented in a subclass. An interface and an abstract class above look simple, you may feel as if nothing is being done, the implementation does not do anything, but it can be a great help for development. We can inherit the abstract class according to our own needs, and the data can be obtained in various ways, such as directly through a List, or through JDBC, Hibernate, etc., but we all need to encapsulate the results into a List, which is especially convenient through Hibernate.

PageException is a custom exception


package treeroot.util   

public class PageException extends Exception
{
  public PageException(){
    super();
  }
  public PageException(String message){
    super(message);
  }
}


Related articles: