JSP page technology implementation

xiaoxiao2021-03-06  39

Use tool class to implement universal paging processing original published in JavaResearch.org

Currently, the paging mode is to cacize the query results in httpsession or state beans, and remove one page data from the cache when turning pages. This approach has two main disadvantages: First, the user may see that expired data; the second is that the first query traversal assembly takes a long time if the data volume is very large, and the cached data will take up a lot of memory. The efficiency is significantly dropped.

Other common methods include querying a database each time, taken only one page data from the ResultSet (using rs.last (); rs.getrow () get the total number of recordings, use rs.absolute () to locate This page started record). This approach is similar to the JDBC implementation of some databases (such as Oracle). It is also necessary to traverse all records. The experiment proves that the speed is very slow when the number of records is very slow.

As for the cache result set, the method of ResultSet is completely a wrong approach. Because the ResultSet is closed when Statement or Connection is closed, if you want to make the ResultSet effect, you will always take up a database connection.

Therefore, the better paging approach should be data from the block size of the page size from the database every time you turn pages. Thus, although the database is queried each time, the number of records that queries is small, the network transmission data is not large, and if the connection pool can be used, it can be skipped by the most time consuming database connection process. There are various mature optimization techniques in the database to improve query speed, which is much more effective than making a cache in the application server.

The line number of the query result in the Oracle database uses a pseudo column ROWNUM (starting from 1). For example, Select * from Employee Where Rownum <10 Returns the top 10 records. However, because rownum is assigned before the query is sorted, the query Employee is written in the 100th to 120 records sorted by BirthDay:

Select * from (select my_table. *, rownum as my_rownum from (select name, birthday from employee) my_table where rownum <120) where my_rownum> = 100

Mysql can use the LIMIT clause:

Select Name, Birthday from Employee ORDER BY BIRTHDAY LIMIT 99, 20

DB2 has a ROWNUMBER () function to get the current number of rows.

SQL Server has not studied, you can refer to this article:

http://www.9cbs.net/develop/Article/18/18627.shtm

The paging in the web program will be frequently used, but the implementation details of the paging are more troublesome during the programming process. Most pags displayed query operations need to handle complex multiple query conditions, SQL statements require dynamic splicing composed, plus paging required record positioning, total records of records, traversal, package, and display, program meeting Becomes complicated and difficult to understand. Therefore, some tool classes simplify the paging code, so that the programmer focuses on the business logic. Here is two tools I have designed:

PageDStatement encapsulates a database connection, a total record number query, a page query, a result of data package, and shuts down a database connection, and uses preparedStatement supports dynamic setting parameters.

ROWSETPAGE Reference Page By Page Iterator Mode for PetStore, Design RowSetPage for Packaging Query Results (one page with OracleCachedRowSet Cache queries, please refer to the JSP page query display common mode for the use of the CachedRowSet package database query) The number of strips, current record number, etc., and can generate a simple HTML paging code.

The result of the PageDStatement query is encapsulated into rowsetpage.

The following is simple

Use example:

// DAO data query part of the code: ... public RowSetPage getEmployee (String gender, int pageNo) throws Exception {String sql =; // use paging query Oracle database "select emp_id, emp_code, user_name, real_name from employee where gender =?" Implementation, 5 PageDStatement PST = New PageDStatementOracleImpl (SQL, PAGENO, 5); PST.STSTRING (1, GENDER); Return Pst.executeQuery ();} // servlet Processing Query Request section code: ... int Pageno; Try {// You can get user-selected page number Pageno = Integer.PARSEINT (Request.getParameter ("Pageno"));} Catch (Exception EX) {// The default is the first page Pageno = 1;} String Gender = Request.getParameter ("gender"); request.setttribute ("EMPPAGE", MyBean.geTemPloyee (GENDER, PAGENO)); ... // JSP Display Some Code <% @ Page Import = "Page.RowSetPage"%> ... < Script language = "javascript"> Function doQuery () {form1.ActionType.Value = "doQuery"; form1.Submit ();} ...

Gender: "> <% ROWSETPAGE EMPPAGE = ("EMPPAGE"); if (EMPPAGE == NULL) EMPPAGE = ROWSETPAGE.EMPTY_PAGE;%> ... <% // Show total number of pages and current pages (PAGENO) and paginity code. // This DOQUERY is submitted to the JavaScript function name submitted by the query action, and Pageno is the parameter name%>
<% = EMPRS.GETSTRING ("EMP_CODE")%> <% = EMPRS.GETSTRING ("User_Name")%> <% = EMPRS.GETSTRING ("REAL_NAME")%> <} // end while%>
<% = EMPPAGE .GETHTML ("DOQUERY", "DOQUERY", "DOQUERY", "DOQUERY", "Pageno")%> <% = EMPPAGE .GETHTML / td> effect is shown in Figure:

Because paging display is generally accompanied by query conditions and query action, the page should already have the Query Condition and the JavaScript method submitted in the query (as DOQUERY above), so the paging code generated by RowSetPage.gethtml () When the user selects a new page number Directly call up the JavaScript method for the procedure submitted in front. Note that the last query condition needs to be kept at the time of displaying the query results, such as >. At the same time, due to the parameter name of the page, there is therefore also supports multiple paging areas in the same page.

Another paging code implementation is the URL of each page, and the query parameters and page numbers are attached to the URL behind the querystring. The defect of this method is difficult to process when the query condition is complicated, and the servlet that needs to be specified to process the query action may not be suitable for some custom query operations.

If the default paging code generated by RowSetPage.GethTML () can write your own paging processing code, RowSetPage provides a lot of getter methods to obtain relevant information (such as current page numbers, total number of pages, total record number and current record number, etc.) ).

In practical applications, the paging query and display can be made into JSP Taglib, further simplify the JSP code, and mask Java Code.

Attachment: Source code for paging tool classes, annotations should be easily understood.

1.Page.java

2.RowSetPage.java (RowSetPage inherits Page)

3.PagedStatement.java

4.PageDStatementOracleImpl.java (PageDStatementoCleiMPL inherited PagedStatement)

You can use these source code arbitrarily, but you must retain author evan_zhao@hotmail.com words

///////Page.java// Author: evan_ZHAO@hotmail.com////package page; import java.util.list; import java.util.ArrayList; import java.util.collection; import java .util.collections; / ** * Title: Paging object
* Description: Objects used to include data and page information
* Page class implements basic methods for displaying paging information, but not specified The type of data, * Subcounds can be organized according to a specific manner,
* If RowSetPage is encapsulated in RowSet, list Package data
* Copyright: CopyRight (c) 2002
* @ @BR> * @ author evan_zhao@hotmail.com
* @version 1.0 * / public class Page implements java.io.Serializable {public static final Page EMPTY_PAGE = new Page (); public static final int DEFAULT_PAGE_SIZE = 20; public static final int MAX_PAGE_SIZE = 9999; private int myPageSize = DEFAULT_PAGE_SIZE; private int start; private int avaCount, totalSize; private Object data; private int currentPageno; private int totalPageCount; / ** * default constructor, only the configuration of an empty page * / protected page () {this .init (0,0,0, default_page_size, new object ());} / ** * Page data initial method, by subclass call * @Param Start This page data in the start position of this page * @Param Avacount This page * @Param Totalsize database The total number of records in the database * @Param PageSize Page Capacity * @Param Data This page contains data * / protected void init (int Start, int avacount, int us) {this.avacount = avacount; this.mypagesize = PageSize; this.start = start this.totalsize = Totalsize; this.data = data; //system.out.println ("Avacount:" avacount); //system.out.println ("Totalsize:" Totalsize); if (Avacount>

Totalsize) {// throw new runtimeException ("The number of records is greater than the total number of people ?!");} this.currentpageno = (start -1) / pagesize 1; this.totalPageCount = (Totalsize Pagesize -1) / PageSize ; if (Totalsize == 0 && Avacount == 0) {this.currentpageno = 1; this.totalPageCount = 1;} //system.out.println ("start index to page no: " start " - " CurrentPageno;} public object getdata () {return this.data;} / ** * Take this page data capacity (number of records available on this page) * @return this page can contain records * / public int GetPageSize ) {Return this.mypagesize;} / ** * Is there a next page * @return does have next page * / public boolean HasnextPage () {/ * if (Avacount == 0 && totalsize == 0) {Return False } return (start avacount -1) 1; * / return (this.getCurrentPageno ()> 1);} / ** * Get the location of the current page 1 data in the database * @return * / public int GETSTART () {Return Start;} / ** * Get the position of the current page last data in the database * @return * / public int getend () {int end = this.getStart () this.getsize () -1; if (end <0) {end = 0;} return end;} / ** * Get the first page of the first data in the database location * @return records the corresponding ROWNUM * / Public INT getStartofpReviouspage () {Return Math.max (Start-Mypagesize, 1 );

} / ** * Get the next page The position of the first data in the database * @return records the corresponding rownum * / public int getStartofnextPage () {Return Start Avacount;} / ** * Get either first page Data in the location of the database, the number of each page uses the default value * @Param Pageno Page number * @return records the corresponding ROWNUM * / PUBLIC Static Int getStartofanyPage (Int Pageno) {Return GetStartofanyPage (Pageno, Default_page_size);} / ** * Get any page The first data in the database * @Param Pageno Page number * @Param PageSize Each page contains the number of records * @return records the corresponding ROWNUM * / PUBLIC Static Int GetStartofAnpage (int Pageno, int pageize) {Int StartIndex = (PAGENO-1) * Pagesize 1; IF (StartIndex <1) StartIndex = 1; //system.out.println ("Pageno " - " STARTINDEX); Return StartIndex;} / ** * Take the number of records included in this page * @RETURN This page contains the number of records * / public int getSize () {return avacount;} / ** * Take the total record included in the database * @ The total number of records included in the return database * / public int gettotalsize () {return this.totalsize;} / ** * Front page * @return current page * / public int getCurrentPageno () {returnim cc c 取 总 总 * @return total page * / public int getTotalPageCount () {Return this.totalPageCount;} / ** * * @param queryJSFunctionName achieve JS script name paged, will automatically call this method * @param pageNoParamName page parameter name when the page changes * @return * / public String getHTML (String queryJSFunctionName, String pageNoParamName) {if (getTotalPageCount () <1 ) {return "

} If (. QueryJSFunctionName == null || queryJSFunctionName.trim () length () <1) {queryJSFunctionName = "gotoPage";} if (. PageNoParamName == null || pageNoParamName.trim () length () <1) { Pagenoparamname = "Pageno";} String gotopage = "_" queryjsfunctionName; stringbuffer html = new stringbuffer ("/ n"); html.append ("