一.MySQL分页的实现:
Select * from table limit M,N
M:记录开始索引位置
N:取多少条记录。
完成WEB页面的分页显示
先获得需分页显示的记录总数,然后在web页面中显示页码。
根据页码,从数据库中查询相应的记录显示在web页面中。
以上两项操作通常使用Page对象进行封装。

二.Oracle分页语句

select * from (
   select rownum r_, row_.*  from (
     select * from student order by id
   ) row_ where rownum <=5
         ) where r_>=1

1位置:起始索引位置。
5位置:结束索引位置。 

三.分页数据图

四.开发分页流程!!!!!重点!!!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

1.首先开发整个分页功能中供程序访问的3个对象,既,PageInfo,QueryResult,PageBean

PageInfo对象用来封装用户的请求(访问页数currentpage ,每页条数pagesize ,数据库数据起始位置startindex)

public class PageInfo {
 
 private int currentpage = 1; //设置初始值访问第一页
 private int pagesize = 5;   //设置初始值每页条数
 private int startindex;     //根据访问页数和每页条数获得数据库初始位置
 
 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;
 }
 public int getStartindex() {  // //根据访问页数和每页条数获得数据库初始位置
  this.startindex = (this.currentpage-1)*this.pagesize;
  return startindex;
 }
 
}

QueryResult对象用来封装从数据库查询的结果(查询到的数据的集合list,一共多少条记录totalrecord)

public class QueryResult {
 private List list; //记往查询的页面数据
 private int totalrecord; //记住总记录数
 public List getList() {
  return list;
 }
 public void setList(List list) {
  this.list = list;
 }
 public int getTotalrecord() {
  return totalrecord;
 }
 public void setTotalrecord(int totalrecord) {
  this.totalrecord = totalrecord;
 }

 PageBean对象用来封装提供web层获取的数据(封装的指定分页数据集合,封装的用于页码条的数据)

public class PageBean {
 //QueryResult对象中获取需要的属性
 private List list; //封装分页数据
 private int totalrecord; //封装总共多少记录数据
 
 
 private int pagesize;  //从PageInfo对象中获取每页条数信息封装
 private int totalpage; //总页数,根据pagesiaze和totalrecord属性计算出
 private int currentpage;//从PageInfo对象中获取当前页信息封装
 
 private int previouspage; //封装上一页属性
 private int nextpage;   //封装下一页属性
 
 private int pagebar[]; //封装页码块属性
 
 
 public List getList() {
  return list;
 }
 public void setList(List list) {
  this.list = list;
 }
 public int getTotalrecord() {
  return totalrecord;
 }
 public void setTotalrecord(int totalrecord) {
  this.totalrecord = totalrecord;
 }
 public int getPagesize() {
  return pagesize;
 }
 public void setPagesize(int pagesize) {
  this.pagesize = pagesize;
 }
 public int getTotalpage() {  //获取总共多少页属性,根据pagesiaze算出
  if(this.totalrecord%this.pagesize==0){
   this.totalpage = this.totalrecord/this.pagesize;
  }else{
   this.totalpage = this.totalrecord/this.pagesize+1;
  }
  
  return totalpage;
 }
 
 public int getCurrentpage() {
  return currentpage;
 }
 public void setCurrentpage(int currentpage) {
  this.currentpage = currentpage;
 }
 public int getPreviouspage() { //获取上一页属性,既是获取当前页的上一页
  if(this.currentpage-1<1){
   this.previouspage = 1;
  }else{
   this.previouspage = this.currentpage-1;
  }
  return previouspage;
 }
 
 public int getNextpage() { //获取下一页属性,同理
  if(this.currentpage+1>this.totalpage){
   this.nextpage = this.totalpage;
  }else{
   this.nextpage = this.currentpage+1;
  }
  return nextpage;
 }
 
 public int[] getPagebar() {  //获取页码块属性,这里需要仔细的判断
  
  //页码条的总个数是10个
  if(this.totalpage<=10){   //首先判断如果总页数小于10,那么就遍历出所有页数
   this.pagebar = new int[this.totalpage];
   for(int i=1;i<=this.totalpage;i++){
    this.pagebar[i-1] = i;
   }
   return pagebar;
  }
  
  //由于显示前后5页会出现前后越界问题,所以初始化出2个属性,用于记录起始页和末页  int startpage = this.currentpage - 4;
  int endpage = this.currentpage + 5;
  
  if(startpage<1){   //如果向前4页越界那么设置属性
   startpage = 1;
   endpage = 10;
  }
  
  if(endpage>this.totalpage){ //如果向后5页越界那么设置属性
   endpage = this.totalpage;
   startpage = this.totalpage - 9;
  }
  
  this.pagebar = new int[10]; //如果以上条件都不符合那么根据算出的起始页和末页属性遍历出数组
  int index = 0;
  for(int i=startpage;i<=endpage;i++){
   this.pagebar[index++] = i;
  }
  return pagebar;
 }
}

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

2.开发Dao层中的Dao,从数据库中获取数据并封装出QueryResult对象,以供servec层获取

*Dao层中的CustomerDao接口的实现类CustomerDaoImpl中提供方法获取封装了查询数据的QueryResult对象

//根据传入的参数(分页起始数据库位置,分页数据条数)查询数据库返回封装了数据的对象
public QueryResult pageQuery(int startindex,int pagesize){
  //模板代码
  Connection conn = null; //数据库连接对象
  PreparedStatement st = null; //发送sql语句的安全的发送对象
  ResultSet rs = null;     //结果集对象
  
  QueryResult qr = new QueryResult();  //根据javabean创建封装分页数据的对象
  try{
   conn = JdbcUtils.getConnection(); //获取连接
   String sql = "select * from customer limit ?,?"; //编写sql语句,limit查询分页:起始位置,获取数
   st = conn.prepareStatement(sql); //预编译sql,将传入的属性?替换成起始位置和获取数目
   st.setInt(1, startindex);
   st.setInt(2, pagesize);
   rs = st.executeQuery(); //发送查询
   List list = new ArrayList(); //创建list集合用来封装查询返回出的对象
   while(rs.next()){ //遍历结果集,创建一个对象
    Customer c = new Customer();
    c.setBirthday(rs.getDate("birthday")); //获取结果集中对象的属性并封装到新建的对象中
    c.setCellphone(rs.getString("cellphone"));
    c.setDescription(rs.getString("description"));
    c.setEmail(rs.getString("email"));
    c.setGender(rs.getString("gender"));
    c.setId(rs.getString("id"));
    c.setName(rs.getString("name"));
    c.setPreference(rs.getString("preference"));
    c.setType(rs.getString("type"));
    list.add(c); //向集合中封装对象
   }

   qr.setList(list); //向用来封装查询结果的QueryResult 对象中封装list集合
   

sql = "select count(*) from customer"; //编写另一条sql语句用来获取总数据条数
   st = conn.prepareStatement(sql);
   rs = st.executeQuery();
   
   if(rs.next()){
    qr.setTotalrecord(rs.getInt(1));  //将获得的总条数数据封装到QueryResult 对象中
   }
   return qr;  //将封装好的QueryResult 对象返回出去,提供给调用它的servec层
  }catch (Exception e) {
   throw new DaoException(e);
  }finally{
   JdbcUtils.release(conn, st, rs); //释放资源
  }
 }

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

3.开发servec层中的BusinessService 类,用来为web层提供一个封装了QueryResult中数据的PageBean对象

public class BusinessService {
//通过DaoFactory工厂类获取用来操作QueryResult对象的dao
 private CustomerDao customerDao = DaoFactory.getInstance().createDao();
//提供一个pageQuery方法通过web层传入的pageInfo对象,封转并返回出提供web层获取的PageBean对象 
 public PageBean pageQuery(PageInfo pageInfo){
  //从传入的pageInfo对象中获取(数据库起始位置,分页条数)属性,调用Dao类中的方法获取QueryResult 
  QueryResult qr = customerDao.pageQuery(pageInfo.getStartindex(), pageInfo.getPagesize());
  //创建出供web层获取的pageBean对象,并封装属性
  PageBean pageBean = new PageBean();
  pageBean.setCurrentpage(pageInfo.getCurrentpage());
  pageBean.setList(qr.getList());
  pageBean.setPagesize(pageInfo.getPagesize());
  pageBean.setTotalrecord(qr.getTotalrecord());
  
  return pageBean; //返回一个封装好的pageBean对象
 }

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

4.开发web层中的servlet,用来获取servec层中提供的封装了分页数据的PageBean对象,并存入request域中,提供给JSP直接获取该次查询出的对象

public class ListCustomerServlet extends HttpServlet {
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {//通过工具类创建一个封装了用户请求的request对象的pageInfo对象
  PageInfo pageInfo = WebUtils.request2Bean(request, PageInfo.class);
  BusinessService service = new BusinessService(); //获取servec对象
  PageBean pageBean = service.pageQuery(pageInfo); //调用pageQuery方法传入封装了请求信息的pageInfo对象获取封装了分页数据的PageBean对象
  request.setAttribute("pageBean", pageBean); //向request域中存入pageBean对象
  //转发存储了pageBean对象的request对象到具体的JSP页面供web获取pageBean
  request.getRequestDispatcher("/WEB-INF/jsp/listcustomer.jsp").forward(request, response);
  
 } public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  doGet(request, response);
 }

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

5.开发JSP,制作表单获取分页数据显示

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   //导入JSTL中的核心标签库
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> //导入JSTL中函数标签库
<%@taglib uri="/WEB-INF/my.tld" prefix="itcast" %> //导入自定义标签<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>显示所有用户</title>
    <style type="text/css">
     .even{background-color: #FFFF66}
     .odd{background-color: #FF99FF}
     tr:hover{background-color: #0066FF}
    </style>
  </head>
 
  <body >
   <br/><br/>
 
    <table width="90%" border="1">
     <tr>
      <td>客户姓名</td>
      <td>性别</td>
      <td>生日</td>
      <td>手机</td>
      <td>邮箱</td>
      <td>爱好</td>
      <td>类型</td>
      <td>备注</td>
      <td>操作</td>
     </tr>
     <!-- forEach标签遍历pageBean对象中的list集合-->
     <c:forEach var="c" items="${pageBean.list}" varStatus="status">
      <tr class="${status.count%2==0?'even':'odd' }">
       <td>${c.name }</td>
       <td>${c.gender }</td>
       <td>${c.birthday }</td>
       <td>${c.cellphone }</td>
       <td>${c.email }</td>
       <td>${c.preference }</td>
       <td>${c.type }</td>
       <td>${fn:escapeXml(c.description)}</td>
       <td>      <!--给修改客户设置一个超链接,去访问一个servlet并带去参数id -->
        <a href="${pageContext.request.contextPath }/servlet/EditCustomerUIServlet?id=${c.id }">修改客户</a>      <!--给删除客户设置一个超链接,去访问一个function标签并带去参数id -->
        <a href="javascript:void(0)" οnclick="del('${c.id }')">删除客户</a>
       </td>
      </tr>
     </c:forEach>
    </table>
   
    <script type="text/javascript">
     <!--javascript方法-->
     function del(id){
      var b = window.confirm("删除吗?");
      if(b){
       window.location.href="${pageContext.request.contextPath}/servlet/DeleteCustomerServlet?id=" + id;
      }
     }
     <!--页码块方法-->
     function gotopage(pagenum){
      var pagesize = document.getElementsByName("pagesize")[0].value;
      window.location.href="${pageContext.request.contextPath}/servlet/ListCustomerServlet?currentpage=" + pagenum + "&pagesize=" + pagesize;
     }
     <!--GO跳转方法-->
     function goWhich(input){
      var pagesize = document.getElementsByName("pagesize")[0].value;
      var pagenum = input.value;
      window.location.href="${pageContext.request.contextPath}/servlet/ListCustomerServlet?currentpage=" + pagenum + "&pagesize=" + pagesize;
     }
    </script>
     <!--从pageBean对象中获取相应的属性-->
    共[${pageBean.totalrecord }]记录,
    每页<input type="text" name="pagesize" value="${pageBean.pagesize }" >条,
    共[${pageBean.totalpage }]页,
    当前[${pageBean.currentpage }]页
         
    <a href="javascript:void(0)" οnclick="gotopage(${pageBean.previouspage })">上一页</a> 
  <!--forEach标签判断当前页和遍历出页码块数字是否相同,以直观看出当前页数-->
     <c:forEach var="pagenum" items="${pageBean.pagebar}">
      <c:if test="${pageBean.currentpage!=pagenum}">
       <a href="javascript:void(0)" οnclick="gotopage(${pagenum })">${pagenum }</a>
      </c:if>
      <c:if test="${pageBean.currentpage==pagenum}">
       <font color="red">${pagenum }</font>
      </c:if>
     </c:forEach>
    <a href="javascript:void(0)" οnclick="gotopage(${pageBean.nextpage })">下一页</a>
   
    跳转到<input type="text" name="pagenum" id="pagenum">
    <input type="button" value=" GO " οnclick="goWhich(document.getElementByIdx_x('pagenum'))">
  </body>
</html>