Immediately after the previous article - The principles of paging technology and the significance and methods of paging (I). This article continues to analyze paging technology. The previous article talks about the simple principles and introduction of pagination technology. This article deeply analyzes the code implementation of pagination technology.
In the last article, the best implementation of paging is to paginate at the database layer, and different databases have different paging implementations. For example, Oracle uses three-layer SQL nesting to implement paging, and MySQL uses the limit keyword to implement limit (mentioned in the previous article).
This article is based on Java + Oracle and explains the implementation of the code layer .
As we usually see in paging, the returned query result not only includes the query result set (List), but also includes the total number of pages (pageNum), the current page (pageNo), and other information. Therefore, we encapsulate a query result PageModel class, the code is as follows:
package kane;import java.util.List;public class PageModel<E> { private List<E> list; private int pageNo; private int pageSize; private int totalNum; private int totalPage; public List<E> getList() { return list; } public void setList(List<E> list) { this.list = list; } public int getPageNo() { return pageNo; } public void setPageNo(int pageNo) { this.pageNo = pageNo; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalNum() { return totalNum; } public void setTotalNum(int totalNum) { this.totalNum = totalNum; setTotalPage((getTotalNum() % pageSize) == 0 ? (getTotalNum() / pageSize) : (getTotalNum() / pageSize + 1)); } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } // Get the first page public int getFirstPage() { return 1; } // Get the last page public int getLastPage() { return totalPage; } // Get the previous page public int getPrePage() { if (pageNo > 1) return pageNo - 1; return 1; } // Get the last page public int getBackPage() { if (pageNo < totalPage) return pageNo + 1; return totalPage; } // Get the last page public int getBackPage() { if (pageNo < totalPage) return pageNo + 1; return totalPage; } // Measure whether 'home page' and 'front page' are available public String isPreable() { if (pageNo == 1) return "disabled"; return ""; } // Measure whether 'last page' and ' next page' are available public String isBackable() { if (pageNo == totalPage) return "disabled"; return ""; }} The use of generics is to enable the paging class to be reused. For example, when querying users, the User object can be encapsulated, and when querying flow orders in finance, the FlowCard class can be encapsulated.
We take the query user as an example. The user selects the query condition, first call the Servlet to obtain the query parameters, and then request the business logic layer to obtain the paginated encapsulation result class. The business logic calls the Dao layer to obtain the result set and obtain the records in the process. The number of records in the process is encapsulated into the page class. Finally, the Servlet sets the result to the jsp page to display.
First, let’s explain the Servlet, the code is as follows:
package kane;import java.io.*;import java.util.*;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import kane.UserInfo;import kane.UserInfoManage;import kane.PageModel;public class UserBasicSearchServlet extends HttpServlet { private static final long serialVersionUID = 1L; private int pageSize = 0; @Override public void init(ServletConfig config) throws ServletException { pageSize = Integer.parseInt(config.getInitParameter("pageSize")); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. Get page parameters and construct the parameter object int pageNo = Integer.parseInt(req.getParameter("pageNo")); String sex = req.getParameter("gender"); String home = req.getParameter("newlocation"); String college = req.getParameter("colleage"); String coming year = req.getParameter("ComingYear"); UserInfo u = new UserInfo(); u.setSex(sex); u.setHome(home); u.setColleage(colleage); u.setCy(comingyear); // 2. Call business logic to obtain the result set UserInfoManage userInfoManage = new UserInfoManage(); PageModel<UserInfo> pagination = userInfoManage.userBasicSearch(u, pageNo, pageSize); List<UserInfo> userList = pagination.getList(); // 3. Encapsulate the return result StringBuffer resultXML = new StringBuffer(); try { resultXML.append("<?xml version='1.0' encoding='gb18030'?>/n"); resultXML.append("<root>/n"); for (Iterator<UserInfo> iterator = userList.iterator(); iterator .hasNext();) { UserInfo userInfo = iterator.next(); resultXML.append("<data>/n"); resultXML.append("/t<id>" + userInfo.getId() + "</id>/n"); resultXML.append("/t<truename>" + userInfo.getTruename() + "</ truename >/n"); resultXML.append("/t<sex>" + userInfo.getSex() + "</sex>/n"); resultXML.append("/t<home>" + userInfo.getHome() + "</home>/n"); resultXML.append("/t<home>" + userInfo.getHome() + "</home>/n"); resultXML.append("</data>/n"); } resultXML.append("<pagination>/n"); resultXML.append("/t<total>" + pagination.getTotalPage() + "</total>/n"); resultXML.append("/t<start>" + pagination.getFirstPage() + "</start>/n"); resultXML.append("/t<end>" + pagination.getLastPage() + "</end>/n"); resultXML.append("/t<pageno>" + pagination.getPageNo() + "</pageno>/n"); resultXML.append("</pagination>/n"); resultXML.append("</root>/n"); } catch (Exception e) { e.printStackTrace(); } writeResponse(req, resp, resultXML.toString()); } public void writeResponse(HttpServletRequest request, HttpServletResponse response, String result) throws IOException { response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Content-Type", "text/xml; charset=gb18030"); PrintWriter pw = response.getWriter(); pw.write(result); pw.close(); }} The User object code is as follows:
package kane;import java.util.Date;public class UserInfo { private int id; private String username; private String password; private String truename; private String sex; private Date birthday; private String home; private String college; private String coming Year; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getTruename() { return truename; } public void setTruename(String truename) { this.truename = truename; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getHome() { return home; } public void setHome(String home) { this.home = home; } public String getColleage() { return college; } public void setColleage(String colleague) { this.colleage = college; } public String getCy() { return comingYear; } public void setCy(String cy) { this. comingYear= cy; }} Next is the business logic layer code, the code is as follows:
package kane;import java.sql.Connection;import kane.DBUtility;import kane.PageModel;public class UserInfoManage { private UserInfoDao userInfoDao = null; public UserInfoManage () { userInfoDao = new UserInfoDao(); } public PageModel<UserInfo> userBasicSearch(UserInfo u, int pageNo, int pageSize) throws Exception { Connection connection = null; PageModel<UserInfo> pagination = new PageModel<UserInfo>(); try { connection = DBUtility.getConnection(); DBUtility.setAutoCommit(connection, false); pagination.setList(userInfoDao.getUserList(u, pageNo, pageSize)); pagination.setPageNo(pageNo); pagination.setPageSize(pageSize); pagination.setTotalNum(userInfoDao.getTotalNum(u)); DBUtility.commit(connection); } catch (Exception e) { DBUtility.rollBack(connection); e.printStackTrace(); throw new Exception(); } finally { DBUtility.closeConnection(); } return pagination; }} Where DBUtility is the connection encapsulation class of the database.
Finally, the Dao layer code implementation is as follows:
package kane;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import java.util.List;import kane.UserInfo;import kane.DBUtility;public class UserInfoDao { public List<UserInfo> getUserList(UserInfo userInfo, int pageNo, int pageSize) throws Exception { PreparedStatement pstmt = null; ResultSet rs = null; List<UserInfo> userList = null; try { String sql = "select * from(select rownum num,u.* from(select * from user_info where sex = ? and home like '" + userInfo.getHome() + "%" + "' and colleague like '" + userInfo.getColleage() + "%" + "' and coming year like '" + userInfo.getCy() + "%" + "' order by id) u where rownum<=?) where num>=?"; userList = new ArrayList<UserInfo>(); Connection conn = DBUtility.getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, userInfo.getSex()); pstmt.setInt(2, pageNo * pageSize); pstmt.setInt(3, (pageNo - 1) * pageSize + 1); rs = pstmt.executeQuery(); while (rs.next()) { UserInfo user = new UserInfo(); user.setId(rs.getInt("id")); user.setTruename(rs.getString("truename")); user.setSex(rs.getString("sex")); user.setHome(rs.getString("home")); userList.add(user); } } catch (SQLException e) { e.printStackTrace(); throw new Exception(e); } finally { DBUtility.closeResultSet(rs); DBUtility.closePreparedStatement(pstmt); } return userList; } public int getTotalNum(UserInfo userInfo) throws Exception { PreparedStatement pstmt = null; ResultSet rs = null; int count = 0; try { String sql = "select count(*) from user_info where sex=? and home like '" + userInfo.getHome() + "%" + "' and college like '" + userInfo.getColleage() + "%" + "' and coming year like '" + userInfo.getCy()+ "%" + "'"; Connection conn = DBUtility.getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, userInfo.getSex()); rs = pstmt.executeQuery(); if (rs.next()) { count = rs.getInt(1); } } catch (SQLException e) { e.printStackTrace(); throw new Exception(e); } finally { DBUtility.closeResultSet(rs); DBUtility.closePreparedStatement(pstmt); } return count; }} Finally, the servlet returns the result to the jsp page to display.
Note: The DBUtility code is the code that encapsulates the database connection operation, as follows:
package kane;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class DBUtility { private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); public static Connection getConnection() { Connection conn = null; conn = threadLocal.get(); if (conn == null) { try { Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:oracle", "admin", "admin"); threadLocal.set(conn); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } return conn; } // Encapsulation settings Connection automatically submits public static void setAutoCommit(Connection conn, Boolean flag) { try { conn.setAutoCommit(flag); } catch (SQLException e) { e.printStackTrace(); } } // Set transaction commit public static void commit(Connection conn) { try { conn.commit(); } catch (SQLException e) { e.printStackTrace(); } } // Encapsulation Set Connection Rollback public static void rollBack(Connection conn) { try { conn.rollback(); } catch (SQLException e) { e.printStackTrace(); } } // Encapsulate the function that closes Connection, PreparedStatement, and ResultSet public static void closeConnection() { Connection conn = threadLocal.get(); try { if (conn != null) { conn.close(); conn = null; threadLocal.remove(); } } catch (SQLException e) { e.printStackTrace(); } } public static void closePreparedStatement(PreparedStatement pstmt) { try { if (pstmt != null) { pstmt.close(); pstmt = null; } } catch (SQLException e) { e.printStackTrace(); } } public static void closeResultSet(ResultSet rs) { try { if (rs != null) { rs.close(); rs = null; } } catch (SQLException e) { e.printStackTrace(); } }} ThreadLocal is used to ensure the consistency of transactions, so that all database operations of the same thread use the same Connection.
At this point, a simple code implementation is completed.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.