现在的位置: 首页 > 综合 > 正文

分页的极致

2018年05月17日 ⁄ 综合 ⁄ 共 15165字 ⁄ 字号 评论关闭
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!-- 
	以前的那个是老的HTML标准,不是因为浏览器不支持,因为这个网页你告诉浏览器它是老的,
	浏览器不会用新的,现在我们用新规范的网页,所以IE浏览器就把它按照新的规范去搞。
	其实你可以去大的网站它的的标准老师按照新的。
 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <style type="text/css">
    	.odd{background-color: #f3c3f3}
    	.even{background-color: #c3f3c3}
    	tr:hover{background-color: #888}
    </style>
    
    
 	<script type="text/javascript">
 		function gotoPage(pid){
 	 		var psize = document.getElementById("psize").value;
			window.location.href="${pageContext.request.contextPath}/servlet/PageListServlet?pid="+pid+"&psize="+psize;
 	 	}
 	</script>

  </head>
  
  <body>
    <table width="80%" border="1" style="border-collapse: collapse;" border-color="gray">
    	<colgroup align="center"></colgroup>
    	<colgroup align="center"></colgroup>
    	<c:forEach items="${pageBean.beanList}" var="page" varStatus="status">
    		<tr class="${status.count%2==1?'odd':'even'}">
    			<td>
    				${page.id}
    			</td>
    			<td>
    				${page.name}
    			</td>
    		</tr>
    	</c:forEach>
    	
    </table>
    	总共${pageBean.totalRecords}条记录|每页显示${pageBean.pageSize}
    										<input id="psize" type="text" value="${pageBean.pageSize}" style="width: 20px" />
    	|总共有${pageBean.totalPages}页|当前是第${pageBean.currentPage}页
    	<c:if test="${not pageBean.firstPage}">
    		<a href="${pageContext.request.contextPath}/servlet/PageListServlet?pid=1">首页</a>
    		<a href="${pageContext.request.contextPath}/servlet/PageListServlet?pid=${pageBean.previousPage}">上一页</a>
    	</c:if>
    	
    	<c:forEach items="${pageBean.pageBar}" var="pageNumber">
    		<c:if test="${pageNumber==pageBean.currentPage}">${pageNumber}</c:if>
    		<c:if test="${pageNumber!=pageBean.currentPage}">
    			<a href="${pageContext.request.contextPath}/servlet/PageListServlet?pid=${pageNumber}">${pageNumber}</a>
    		</c:if>
    	</c:forEach>
    	
    	
    	<c:if test="${not page.lastPage}">
    		<a href="${pageContext.request.contextPath}/servlet/PageListServlet?pid=${pageBean.nextPage}">下一页</a>
    		<a href="${pageContext.request.contextPath}/servlet/PageListServlet?pid=${pageBean.totalPages}">尾页</a>
    	</c:if>
    	
    	跳转到
    		<select onchange="gotoPage(this.value)">
    			<c:forEach begin="1" end="${pageBean.totalPages}" var="pageNumber">
    				<option value="${pageNumber}" ${pageNumber==pageBean.currentPage?"selected='selected'":""}>${pageNumber}/${pageBean.totalPages}</option>
    			</c:forEach>
    		</select>
  </body>
</html>
package cn.itcast.servletday13.business.dao;

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 com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
import com.sun.org.apache.regexp.internal.recompile;

import cn.itcast.servletday13.business.domain.Page;
import cn.itcast.servletday13.business.util.JdbcUtils;

public class PageDao {
	/*
	 *从第几条开始最多取几条。 
	 */
	public QueryResult getPageQueryResult(int firstRecord,int maxRecords){
		QueryResult queryResult = new QueryResult();
		
		queryResult.setTotalRecords(getTotalRecords());
	
		queryResult.setBeanList(getPageData(firstRecord, maxRecords));
		
		return queryResult;
	}
	/**
	 * 获取数据库中总记录数
	 * @return
	 */
	public  int getTotalRecords() {
		//获取数据库中总记录数
		Connection connection = null;
		PreparedStatement statement = null;
		ResultSet rs = null;
		try {
			connection = JdbcUtils.getConnection();//得到连接
			String sql = "select count(*) from page";
			statement = connection.prepareStatement(sql);//让连接去预编译
			rs = statement.executeQuery();//让状态执行。
			while (rs.next()) {
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			JdbcUtils.realase(connection, statement, rs);
		}
		return 0;
	}

	/*
	 *得到每页要显示的数据。 
	 */
	public List<Page> getPageData(int startindex, int pagesize){
		Connection connection = null;
		PreparedStatement statement = null;
		ResultSet rs = null;
		List<Page> list = new ArrayList<Page>();
		try {
			connection = JdbcUtils.getConnection();
			String sql = "select * from page limit ?,?";
			statement = connection.prepareStatement(sql);
			statement.setInt(1, startindex);
			statement.setInt(2, pagesize);
			rs = statement.executeQuery();
			while (rs.next()) {
				Page page = new Page();
				page.setId(rs.getInt("id"));
				page.setName(rs.getString("name"));
				list.add(page);
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}finally{
			JdbcUtils.realase(connection, statement, rs);
		}
		return list;
	};
	
}
package cn.itcast.servletday13.business.dao;

import java.util.List;

public class QueryResult {
	private int totalRecords;
	private List beanList;
	public int getTotalRecords() {
		return totalRecords;
	}
	public void setTotalRecords(int totalRecords) {
		this.totalRecords = totalRecords;
	}
	public List getBeanList() {
		return beanList;
	}
	public void setBeanList(List beanList) {
		this.beanList = beanList;
	}
	@Override
	public String toString() {
		return "QueryResult [beanList=" + beanList + ", totalRecords="
				+ totalRecords + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((beanList == null) ? 0 : beanList.hashCode());
		result = prime * result + totalRecords;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		QueryResult other = (QueryResult) obj;
		if (beanList == null) {
			if (other.beanList != null)
				return false;
		} else if (!beanList.equals(other.beanList))
			return false;
		if (totalRecords != other.totalRecords)
			return false;
		return true;
	}
	
	
	
	
	

}
package cn.itcast.servletday13.business.domain;
/**
 * 
 * @author Administrator
 * 它是与数据库对应的实体类。
 */
public class Page {
	private int id;
	private String name;
	public Page() {
		// TODO Auto-generated constructor stub
	}
	
	private Page(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	

}

package cn.itcast.servletday13.business.domain;

import java.util.List;

public class PageBean {
	/**
	 * 每次在下面显示几个,其实一般是显示九个,我们数据少显示5个。
	 */
	private final  static int PAGEBARSIZE = 5;
	/**
	 * 数据库中共有多少条记录
	 */
	private int totalRecords;
	/**
	 * 每页显示几条数据,这个是也是写程序的时间设定的,如果百度搜索就是显示10个。
	 */
	private int pageSize;//
	/**
	 * 根据数据库中总共的记录数和每页的大小,算出共有多少页。
	 */
	private int totalPages;
	/**
	 * 显示当前是几页
	 */
	private int currentPage;
	
	
	private int previousPage;
	
	private int nextPage;
	
	
	/**
	 * 判断是否是第一页
	 */
	private boolean firstPage;
	/**
	 * 判断是否是最后一页
	 */
	private boolean lastPage;
	/**
	 * 下面页码条的集合。
	 */
	private int[] pageBar;
	/**
	 * 所有Bean的集合。
	 */
	private List beanList;
	public int getTotalRecords() {
		return totalRecords;
	}
	public void setTotalRecords(int totalRecords) {
		this.totalRecords = totalRecords;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getTotalPages() {
		return totalPages;
	}
	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		//?--->100页,结果可能是50页如果只有50页,而我们要到第100页,
//		所以我们要判断,如果超出了则让其到最后 一页,我们不在这里判断 , 在manager里面调用 。
		this.currentPage = currentPage;
	}
	public boolean isFirstPage() {
		
		return this.currentPage==1;
	}
	public void setFirstPage(boolean firstPage) {
		this.firstPage = firstPage;
	}
	public boolean isLastPage() {
		return this.currentPage==getTotalPages();
	}
	public void setLastPage(boolean lastPage) {
		this.lastPage = lastPage;
	}
	public int[] getPageBar() {
		//除以是为取整,看看是否超出了页码的最大范围,如果没有超出则为0,仍然从
		//第一页开始,如果超出了则为1,2,3,4.。。再乘以它,加1,即为开始的页码。
		int startPage = (this.currentPage-1)/PAGEBARSIZE*PAGEBARSIZE+1;
		int endPage = (this.currentPage-1)/PAGEBARSIZE*PAGEBARSIZE+PAGEBARSIZE;
		if(endPage>getTotalPages()){
			endPage = getTotalPages();
		}
		//确定每个页码bar的大小 ,然后赋值。
		int[] pageBar = new int[endPage-startPage+1]; 
		for (int i = 0; i < endPage-startPage+1; i++) {
			pageBar[i] = startPage+i;
		}
		return pageBar;
	}
	public void setPageBar(int[] pageBar) {
		this.pageBar = pageBar;
	}
	public List getBeanList() {
		return beanList;
	}
	public void setBeanList(List beanList) {
		this.beanList = beanList;
	}
	public static int getPagebarsize() {
		return PAGEBARSIZE;
	}
	
	
	//不需要那两个属性但是需要这两个方法,它可根据其它算出来。
	public int getPreviousPage(){
		int previousPage = this.currentPage - 1;
		if (previousPage<1) {
			previousPage = 1;
		}
		return previousPage;
	}
	public int getNextPage(){
		int nextPage = this.currentPage + 1;
		if (nextPage>getTotalPages()) {
			nextPage = totalPages;
		}
		return nextPage;
	}
	

}

package cn.itcast.servletday13.business.domain;

public class PageInfo {
	/**
	 * 当前是第几页
	 */
	private int currentPage;
	/*
	 *每页显示多少 
	 */
	private int pageSize;
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	@Override
	public String toString() {
		return "PageInfo [currentPage=" + currentPage + ", pageSize="
				+ pageSize + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + currentPage;
		result = prime * result + pageSize;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PageInfo other = (PageInfo) obj;
		if (currentPage != other.currentPage)
			return false;
		if (pageSize != other.pageSize)
			return false;
		return true;
	}
	
	

}

package cn.itcast.servletday13.business.manager;



import cn.itcast.servletday13.business.dao.PageDao;
import cn.itcast.servletday13.business.dao.QueryResult;
import cn.itcast.servletday13.business.domain.PageBean;
import cn.itcast.servletday13.business.domain.PageInfo;

public class PageManager {
	private PageDao pageDao = new PageDao();
	//我们有了PageBean,那么我们需要每个页面的参数。所以有了PageInfo.
	public PageBean getCurrentPage(PageInfo info){
		int firstRecord = (info.getCurrentPage()-1)*info.getPageSize();
		QueryResult queryResult = pageDao.getPageQueryResult(firstRecord, info.getPageSize());
		System.out.println(queryResult+"====");
		PageBean pageBean = new PageBean();
		pageBean.setBeanList(queryResult.getBeanList());
		//这个十分巧妙,以前可能用if else 这里用这种更加简单。
		int totalPages = (queryResult.getTotalRecords()-1)/info.getPageSize()+1;
		pageBean.setTotalPages(totalPages);
		
		int currentPage = info.getCurrentPage();
		if (currentPage>totalPages) {
			currentPage = totalPages;
		}
		pageBean.setCurrentPage(currentPage);
		
		pageBean.setPageSize(info.getPageSize());
		
		pageBean.setTotalRecords(queryResult.getTotalRecords());
		
		return pageBean;
		
	}
	

}
package cn.itcast.servletday13.business.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;



public class JdbcUtils {
	private static String driver = null;
	private static String url = null;
	private static String username = null;
	private static String password = null;
	
	static{
		try {
			//先从配置里面读取信息
			//在类路径下即src下,就通过类加载器来读取。
			InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
			Properties properties = new Properties();
			properties.load(inputStream);
			driver = properties.getProperty("driver");
			url = properties.getProperty("url");
			username = properties.getProperty("username");
			password = properties.getProperty("password");
			System.out.println(driver+url+username+password);
			Class.forName(driver);
		} catch (Exception e) {
			throw new ExceptionInInitializerError();
		}
		
		
	}
	
	public static Connection getConnection() throws SQLException{
		return DriverManager.getConnection(url, username, password);
	}
	
	
	public static void realase(Connection connection,Statement statement,ResultSet rs){
		if (rs!=null) {
			try {
				rs.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			rs=null;
		}
		
		if (statement!=null) {
			try {
				statement.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			statement=null;
		}
		
		
		if (connection!=null) {
			try {
				connection.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			connection=null;
		}
		
	}
	
	
	//
	

}

package cn.itcast.servletday13.business.web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;

import cn.itcast.servletday13.business.domain.PageBean;
import cn.itcast.servletday13.business.domain.PageInfo;
import cn.itcast.servletday13.business.manager.PageManager;

public class PageListServlet extends HttpServlet {

	/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//这就是MVC,不直接访问通过servelt访问,并且在访问时间把一些东西也转发过去 。
		PageManager pageManager = new PageManager();
		PageInfo pageInfo = new PageInfo();
		String pid = request.getParameter("pid");
		int currentPage = 1;
		try {
			currentPage = Integer.parseInt(pid);
		} catch (Exception e) {
			// TODO: handle exception
		}
		String pSize = request.getParameter("psize");
		int pageSize = 10 ;//每页显示默认为10。
		try {
			pageSize = Integer.parseInt(pSize);
		} catch (Exception e) {
			// TODO: handle exception
		}
		pageInfo.setCurrentPage(currentPage);
		pageInfo.setPageSize(pageSize);
		System.out.println(pageInfo.getCurrentPage());
		System.out.println(pageInfo.getPageSize());
		//写代码先写核心,把最主要的写上,其它都是慢慢添加。下面三句是MVC中最核心的。
		PageBean pageBean = pageManager.getCurrentPage(pageInfo);
		request.setAttribute("pageBean",pageBean);
		request.getRequestDispatcher("/WEB-INF/pageList.jsp").forward(request, response);
		
	}

}

分页步骤:
根据MVC设计模式 将页面记录放在一个javabean对象里面

javabean对象里面的属性则根据页面显示的效果进行设置

谁来创建javabean对象呢?
大的方面来说是servlet创建的javabean对象,小的方面来说

javabean对象是由servlet调用别的模块,通常是service/manger来

创建的.

dao层专门用来处理数据库

业务逻辑层:service/manager层是dao层的上一层,一般传递参数

给dao层

在该分页案例里:

PageManager的输入和输出:
PageManager使用PageInfo(参数对象)对象输出PageBean对象

PageDao层通过SQL语句查询出结果,把查询出的结果输出到

QueryResult对象里.

   1.先创建

web,business,business.domain,business.manger,business.dao

几个包

   2.在business.domain中创建PageBean.java 完成这个类
根据页面的属性设置PageBean的属性。
PageBean的属性有当前页面数currentPage,总页面数totalPages

,总记录数totalRecoreds,单位页面记录数pageSize,上一页

previousPage,下一页nextPage,是否是第一页firstPage,是否是

最后一页lastPage,页码条数组pageBar,页面记录的集合beanList
完善各个属性对应的setter和getter方法

【】发现问题:当前页面和传入的页面可能发生错误,如只有10页,

却传入了20页,这时就应该把currentPage放在manager里进行处理

.又发现上一页和下一页不需要定义这个属性,可以直接在

getPreviousPage()里设定.

getPageBar()方法:
先设置一个final类型的static的常量PAGEBARSIZE,

定义数组开始时的数字:int startPage = (currentPage-

1)/PAGEBARSIZE*PAGEBARSIZE+1;

定义数组结束时的数字:int endPage = (currentPage-

1)/PAGEBARSIZE*PAGEBARSIZE+PAGEBARSIZE;

再判断endPage 
if(endPage>getTotalPages()){
endPage = getTotalPages();
}

再补充这个数组
int[] pageBar = new int[endPage-startPage+1];

3.在business.manager中创建PageManager.java类  完成这个类

pageManager类要返回一个pageBean对象,要想返回pageBean对

象,就得传入一个pageInfo对象,用getCurrentPage(pageInfo 

info)方法获得pageBean对象.

所以先在business.manager里创建pageInfo类。

pageInfo类的属性就是传入的当前页面currentPage和单位页面记录

数pageSize.

完成getCurrentPage()方法,需要在方法内部调用一个dao处理数据

库,所以创建一个PageDao类.

在pageDao里设置一个getPageQueryResult()方法,得到结果集

queryResult对象。

注意:把queryResult类设计在dao包里面。里面存放记录总数

totalRecords和记录集合beanList.

我的错误:DAO层要写正确
connection = 

JdbcUtils.getConnection();//得到连接
String sql = "select count(*) from 

page";
statement = 

connection.prepareStatement(sql);//让连接去预编译
rs = statement.executeQuery

();//让状态执行。
根据MVC思想,先访问一个serlvet,然后把该传的数据在这里给它

传进去。
应该把数据放在一个bean里面传进去,那么如何获取这个bean就是

自己要
写的,在页面上用的也这个bean里面的数据。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 

Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
这是HTML新规范,这样才能支持更多的。
<style type="text/css">
     .odd{background-color: #f3c3f3}
     .even{background-color: #c3f3c3}
     tr:hover{background-color: #888}
    </style>
    
    
  <script type="text/javascript">
  function gotoPage(pid){
  var psize = 

document.getElementById("psize").value;

window.location.href="${pageContext.request.contextPath}/

servlet/PageListServlet?pid="+pid+"&psize="+psize;
  }
  </script>

<c:forEach items="${pageBean.beanList}" var="page" 

varStatus="status">
     <tr class="${status.count%

2==1?'odd':'even'}">
     <td>
     ${page.id}
     </td>
     <td>
     ${page.name}

</td>
     </tr>
     </c:forEach>

html中表格的本质就一个格一个格的,而不是我们看到的表格,
如果我们设置为border=1,那么其实它的表格宽度就是2了。

【上篇】
【下篇】

抱歉!评论已关闭.