JavaWeb前台分页与后台分页总结

分页的目的

  • 前台分页
    1、提高性能,在某些情况下,我们并不需要查询很大的数据量,在这种情况下,我们在程序中开辟一个内存(其实就是自己定义一个变量~),专门用来存放查询数据,这样每次点击上一页,下一页,就不必每次和数据库进行交互
  • 后台分页
    1、提高性能,一次查20个,比一次查20000个性能肯定更好;另外如果数据量很大,一次性将内容都查询出来,查询出来的结果是放在内存里面的,内存没有这么大
    2、不需要这么多数据,如新闻,一般人可能只看最近前20条;如果我们将后面的也都查询出来了,就是浪费
    3、展现层面的考虑:如果一次展现太多的数据,不管是排版,还是美观上都不好
  • 任何工具都存在优点与缺点,关键在于如何根据实际情况选择恰当的分页方式~

这里是前台页面~
这里写图片描述

前台分页

原理:前台分页也叫假分页,具体实现原理就是一次性从数据库中将需要的数据全部查询出来,放入程序开辟的一个内存 (其实就是自己定义的一个变量) 中,然后每次取数据都从内存 (还是那个变量)中取,不用频繁与数据库进行交互,适用于查询数据较少的情况。

首先来解释一下下面代码的大体意思:

  1. 在前台JSP页面JS脚本中,定义一个userMgr 对象(自己命名),体现Java面向对象思想,这里看不懂也没关系,后面的前台分页思想看明白就好….首先定义四个变量,用来初始化分页时,其中userDate就是开辟出的内存(自己定义的那个变量~)
  2. 然后是四个函数,分别对应首页,上一页,下一页和尾页功能,这四个函数里的对查询函数和遍历函数的调用就是前台分页的关键,如果不这样做,那么每次查询还是会和数据库进行交互,就失去了前台分页的意义
  3. 然后是查询函数,利用ajax和后台进行数据交互
  4. 最后是数据遍历函数,用来遍历每页数据

代码实现:
这里的后台Sql语句与普通查询无异,就不多赘述。

<script type="text/javascript">
var userMgr = {
        currPage : 1, //当前页
        pageSize : 2, //每页记录数
        totalPage :null, //总页数
        userData :null,  //用于缓存数据的变量

        //对应的按钮写对应的方法响应
        gotoFirst : function(){
            if(userMgr.currPage==1){
                alert("已经是第一页了");
                return;
            }
            userMgr.currPage =1;
            //如果缓存里面有数据,则不进行数据访问,直接利用缓存数据填充页面
            if(userMgr.userData!=null){
                //就不能调用tzQueryUser();
                userMgr.tzFillUserListTable(userMgr.userData);          
            }else{
                userMgr.tzQueryUser();
            }

        },
        gotoBefore : function(){
            userMgr.currPage--;
            if(userMgr.currPage<1){
                alert("已经第一页了");
                return;
            }
            //如果缓存里面有数据,则不进行数据访问,直接利用缓存数据填充页面
            if(userMgr.userData!=null){
                //就不能调用tzQueryUser();
                userMgr.tzFillUserListTable(userMgr.userData);          
            }else{
                userMgr.tzQueryUser();
            }
        },
        gotoNext : function(){
            userMgr.currPage++;
            if(userMgr.currPage>userMgr.totalPage){
                alert("已经是最后一页了");
                return;
            }
            //如果缓存里面有数据,则不进行数据访问,直接利用缓存数据填充页面
            if(userMgr.userData!=null){
                //就不能调用tzQueryUser();
                userMgr.tzFillUserListTable(userMgr.userData);          
            }else{
                userMgr.tzQueryUser();
            }
        },
        gotoLast : function(){
            if(userMgr.currPage==userMgr.totalPage){
                alert("已经是最后一页了");
                return;
            }               
            userMgr.currPage = userMgr.totalPage;
            //如果缓存里面有数据,则不进行数据访问,直接利用缓存数据填充页面
            if(userMgr.userData!=null){
                //就不能调用tzQueryUser();
                userMgr.tzFillUserListTable(userMgr.userData);          
            }else{
                userMgr.tzQueryUser();
            }
        },

        //查询用户方法
        tzQueryUser :function(){
            //这里是模糊查询,获得参数传给后台
            var userNameQuery = $("#userNameQuery").val();      
            $.ajax({
                type:'post',//请求方式
                url:'<%=path%>/pages/user/userAction?method=queryUserList', 
                dataType:'json', //有几种格式 xml html json text 等常用
                //data传值的另外一种方式 form的序列化
                data:{"userNameQuery":userNameQuery},//传递给服务器的参数

                success:function(data){//与服务器交互成功调用的回调函数
                    //data就是out.print输出的内容
                    if(data=='error'){
                        alert("查询用户记录失败");
                    }else{                  
                        userMgr.userData = data;
                        userMgr.tzFillUserListTable(data);                       
                    }
                }
            });
        },

        tzFillUserListTable : function(data){
            var htmlTable = "";
            if(data.length>0){
                //页数:currPage = 1  每页记录条数:pageSize = 2
                //通过页数和每页记录条数,计算显示返回数据数组的那几条记录 
                userMgr.totalPage = Math.ceil(data.length/userMgr.pageSize);
                var beginRow = (userMgr.currPage-1)*userMgr.pageSize;
                var endRow  = userMgr.currPage*userMgr.pageSize;
                //如果通过页数和页记录计算出来的endRow大于数据总记录 ,则讲endRo缩小至data.length
                if(endRow>data.length){
                    endRow = data.length;
                }                       
                //for(var i=0;i<data.length;i++){
                for(var i = beginRow;i<endRow;i++){
                    htmlTable = htmlTable+"<tr>";
                    htmlTable = htmlTable+"<td>";
                    htmlTable = htmlTable+(i+1);
                    htmlTable = htmlTable+"</td>";
                    htmlTable = htmlTable+"<td>";
                    htmlTable = htmlTable+data[i].userName;
                    htmlTable = htmlTable+"</td>";  
                    htmlTable = htmlTable+"<td>";
                    htmlTable = htmlTable+data[i].deptName;
                    htmlTable = htmlTable+"</td>";  
                    htmlTable = htmlTable+"<td>";
                    htmlTable = htmlTable+data[i].roleName;
                    htmlTable = htmlTable+"</td>";  
                    htmlTable = htmlTable+"<td>";
                    htmlTable = htmlTable+data[i].remark;
                    htmlTable = htmlTable+"</td>";  
                    htmlTable = htmlTable+"<td>";
                    htmlTable = htmlTable+getFormatDateByLong(data[i].tvUpdate.time,null);
                    htmlTable = htmlTable+"</td>";  
                    htmlTable = htmlTable+"<td>";

                    var editButton = "<button type='button' class='btn btn-default' id = 'editBtn' onclick='userMgr.tzEditUser(2,"+data[i].userId+");'>修改</button>";
                    var delButton = "<button type='button' class='btn btn-default ' id = 'delBtn' onclick='userMgr.tzDelUser("+data[i].userId+");'>删除</button>";
                    htmlTable = htmlTable+editButton+delButton;
                    htmlTable = htmlTable+"</td>";  

                    htmlTable = htmlTable+"</tr>";
                }

            }else{
                htmlTable = "暂时没有查询到记录 ";

            }
            $('#userListTable').find('tbody').html(htmlTable);
        }
}
</script>

后台查询

原理:后台分页也叫真分页,具体实现原理就是根据不同的数据库,编写不同的分页Sql语句,比如,MySql数据库是根据limit进行分页,而Oracle是根据Rownumber进行分页,这样每次都和数据库进行交互,每次传输数据都不相同。

代码实现:
补充:
一般的分页查询使用简单的 limit 子句就可以实现。limit 子句声明如下:

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
LIMIT 子句可以被用于指定 SELECT 语句返回的记录数。需注意以下几点:

第一个参数指定第一个返回记录行的偏移量
第二个参数指定返回记录行的最大数目
如果只给定一个参数:它表示返回最大的记录行数目
第二个参数为 -1 表示检索从某一个偏移量到记录集的结束所有的记录行
初始记录行的偏移量是 0(而不是 1)
下面是一个应用实例:

select * from orders_history where type=8 limit 1000,10;
该条语句将会从表 orders_history 中查询第1000条数据之后的10条数据,也就是第1001条到第1010条数据。

然后就是后台分页代码部分了~

package com.tz.jspstudy.framework.page.dto;

/**
 * 分页对象,注意其中init()方法是为了校正前台分页传来的分页属性
 * totalRow 某次查询的总记录数  -1就表示这个分页查询是第一次使用 
 * pageNo 当前查询页码 
 * pageSize  每页记录条数   -1 代表查所有的数据
 * begRow 页起始记录行数
 * endRow 页的截止记录行数
 * 类描述:  
 * 类名称:com.tz.jspstudy.framework.page.dto.PageObject       
 * 创建人:keven  
 * 创建时间:2016年8月10日 下午8:44:58     
 * @version   V1.0
 */
public class PageObject implements java.io.Serializable{

    private static final long serialVersionUID = 1L;

    private int totalRow=-1;
    private int pageNo;
    private int pageSize;
    private int begRow;
    private int endRow;

    private final int DEFAULT_PAGESIZE=40;
    private final int MAX_PAGESIZE=1000;


    /**  
     * @return the mAX_PAGESIZE  
     */
    public int getMAX_PAGESIZE() {
        return MAX_PAGESIZE;
    }


    public PageObject(int pageNo,int totalRows){
        this.totalRow = totalRows;
        this.pageNo = pageNo;
        init();

    }


    public PageObject(int pageNo,int pageSize,int totalRows){
        this.totalRow = totalRows;
        this.pageNo = pageNo;
        this.pageSize = pageSize;
        init();
    }


    /**
     * 根据构造数据初始页对象
     */
    private void init() {
        //校正totalRows && pageNo && pageSize
        if (pageNo <= 0) pageNo = 1;
        if (pageSize == 0) pageSize = DEFAULT_PAGESIZE;
        if (pageSize > MAX_PAGESIZE) pageSize = MAX_PAGESIZE;
        if (pageSize > 0){
            begRow = (pageNo - 1 ) * pageSize + 1;
            endRow = pageNo * pageSize;
        } else {
            begRow = 1;
            endRow = MAX_PAGESIZE;
        }
    }



    /**  
     * @return the totalRow  
     */
    public int getTotalRow() {
        return totalRow;
    }
    /**  
     * @param totalRow the totalRow to set  
     */
    public void setTotalRow(int totalRow) {
        this.totalRow = totalRow;
    }
    /**  
     * @return the pageNo  
     */
    public int getPageNo() {
        return pageNo;
    }
    /**  
     * @param pageNo the pageNo to set  
     */
    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }
    /**  
     * @return the pageSize  
     */
    public int getPageSize() {
        return pageSize;
    }
    /**  
     * @param pageSize the pageSize to set  
     */
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    /**  
     * @return the begRow  
     */
    public int getBegRow() {
        return begRow;
    }
    /**  
     * @param begRow the begRow to set  
     */
    public void setBegRow(int begRow) {
        this.begRow = begRow;
    }
    /**  
     * @return the endRow  
     */
    public int getEndRow() {
        return endRow;
    }
    /**  
     * @param endRow the endRow to set  
     */
    public void setEndRow(int endRow) {
        this.endRow = endRow;
    }


    /**  
     * @return the dEFAULT_PAGESIZE  
     */
    public int getDEFAULT_PAGESIZE() {
        return DEFAULT_PAGESIZE;
    }
}

下面来解释一下代码大意:

扫描二维码关注公众号,回复: 2459048 查看本文章
  1. 首先定义四个变量,用来初始化分页,当totalRows 为-1时代表是第一次查询,首先会根据分页查询语句从数据库查询出记录总个数,然后和pageSize 一起用来计算totalPage
  2. 然后是四个函数,分别对应首页、上一页、下一页、尾页,这里和上面前台分页的区别就在于没有了缓存变量和遍历函数,每次都会调用查询方法和后台进行交互
  3. 然后是普通的查询方法
<script type="text/javascript">
    //顶一个js对象
    var userMgr = {
        currPage : 1, //当前页
        pageSize : 2, //每页记录数
        totalRows :-1, //总的记录数
        totalPage :null, //总页数

        //对应的按钮写对应的方法响应
        gotoFirst : function(){
            if(userMgr.currPage==1){
                alert("已经是第一页了");
                return;
            }
            userMgr.currPage =1;
            userMgr.tzQueryUser(); 
            },
        gotoBefore : function(){
            userMgr.currPage--;
            if(userMgr.currPage<1){
                alert("已经第一页了");
                return;
            } 
            userMgr.tzQueryUser();

        },
        gotoNext : function(){
            userMgr.currPage++;
            if(userMgr.currPage>userMgr.totalPage){
                alert("已经是最后一页了");
                return;
            }

            userMgr.tzQueryUser();

        },
        gotoLast : function(){
            if(userMgr.currPage==userMgr.totalPage){
                alert("已经是最后一页了");
                return;
            }               
            userMgr.currPage = userMgr.totalPage;
            userMgr.tzQueryUser();

        },

        //查询用户方法
        tzQueryUser :function(){
            var userNameQuery = $("#userNameQuery").val();      
            $.ajax({
                type:'post',//请求方式
                url:'<%=path%>/pages/user/userAction?method=queryUserList', 
                dataType:'json', //有几种格式 xml html json text 等常用
                //data传值的另外一种方式 form的序列化
                data:{"userNameQuery":userNameQuery,"pageNo":userMgr.currPage,
                      "pageSize" :userMgr.pageSize,"totalRows" :userMgr.totalRows},//传递给服务器的参数
                success:function(data){//与服务器交互成功调用的回调函数
                    //data就是out.print输出的内容
                    if(data=='error'){
                        alert("查询用户记录失败");
                    }else{                  
                        var htmlTable = "";

                        //页数:currPage = 1  每页记录条数:pageSize = 2
                        //通过页数和每页记录条数,计算显示返回数据数组的那几条记录 
                        userMgr.totalPage = Math.ceil(data.totalRows/userMgr.pageSize);//json对象里面的总记录数
                        var userList = data.dataList;//json对象里面详细记录信息
                        var dataNo = (userMgr.currPage-1)*userMgr.pageSize+1;
                        for(var i = 0;i<userList.length;i++){
                            htmlTable = htmlTable+"<tr>";
                            htmlTable = htmlTable+"<td>";
                            htmlTable = htmlTable+(i+dataNo);
                            htmlTable = htmlTable+"</td>";
                            htmlTable = htmlTable+"<td>";
                            htmlTable = htmlTable+userList[i].userName;
                            htmlTable = htmlTable+"</td>";  
                            htmlTable = htmlTable+"<td>";
                            htmlTable = htmlTable+userList[i].deptName;
                            htmlTable = htmlTable+"</td>";  
                            htmlTable = htmlTable+"<td>";
                            htmlTable = htmlTable+userList[i].roleName;
                            htmlTable = htmlTable+"</td>";  
                            htmlTable = htmlTable+"<td>";
                            htmlTable = htmlTable+userList[i].remark;
                            htmlTable = htmlTable+"</td>";  
                            htmlTable = htmlTable+"<td>";
                            htmlTable = htmlTable+getFormatDateByLong(userList[i].tvUpdate.time,null);
                            htmlTable = htmlTable+"</td>";  
                            htmlTable = htmlTable+"<td>";

                            var editButton = "<button type='button' class='btn btn-default' id = 'editBtn' onclick='userMgr.tzEditUser(2,"+userList[i].userId+");'>修改</button>";
                            var delButton = "<button type='button' class='btn btn-default ' id = 'delBtn' onclick='userMgr.tzDelUser("+userList[i].userId+");'>删除</button>";
                            htmlTable = htmlTable+editButton+delButton;
                            htmlTable = htmlTable+"</td>";  

                            htmlTable = htmlTable+"</tr>";
                    } 
                    $('#userListTable').find('tbody').html(htmlTable);                 
                    }
                }
            });
        }
</script>

总结

前台分页与后台分页各有适用的情况,要做到灵活运用,我还有一段路要走~

猜你喜欢

转载自blog.csdn.net/Un_stoppable/article/details/81272196
今日推荐