分页的实现

分页分为前端分页和后端分页,一下是两者是简单实现:

1. 前端分页:

前端分页一般用Jquery插件来实现,一般原理如下:

a. totalPage总页数

b.totalCount符合条件的总记录数

c.pageSize每页显示有多少

d.currentPage 当前第几页

e.pageStart 起始页

f.pageEnd 末页


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>js分页</title>
<style type="text/css">
body { margin: 0; padding: 0; }
.pagination { color: #333; text-align: center; margin: 8px; }
.pagination span { color: #999; margin: 0 1px; padding: 3px 6px; border: 1px solid #ccc; }
.pagination span.on { background-color: #337ab7; color: #fff; font-weight: bold; border: 1px solid #333; }
.pagination a { color: #00f; text-decoration: none; }
.pagination a span { border: 1px solid #66c; color: #33f; }
#pager { margin: 20px; padding: 4px; }
#content { text-align: center; }
</style>
</head>

<body>
<div id="pager"></div>
<div id="content"></div>
<script>
            var currentPage = 1; // 当前页码, 从1开始
            var pageSize = 5; // 每页显示记录数
            var maxButtons = 10; // 显示的分页按钮数量
            var totalCount = 30; // 记录总数
            var totalPage = parseInt(Math.ceil(totalCount / pageSize)); // 总页数
            initPage();

            function initPage() {
                //循环生成数组
                var arr = [];
                for (var o = 0; o < totalCount; o++) {
                    arr.push(o);
                }
                //每一页第一个li
                var rangeStartitem = (currentPage - 1) * pageSize;
                //开始页
                var rangeStart = Math.max(1, currentPage - parseInt(maxButtons / 2));
                //最后一页
                var rangeEnd = Math.min(totalPage, rangeStart + maxButtons - 1);
                
                var constr = pageCon(arr, rangeStartitem, pageSize);
                
                var divcontent = document.getElementById("content");
                divcontent.innerHTML = constr;
                
                //创建分页模板
                var str = "";
                str += "<div class='pagination'>";
                str += "当前第" + currentPage + "页"
                //如果总页数大于1
                if (totalPage > 1) {
                    //当前页不是第一页
                    if (currentPage != 1) {
                        str += '<a href="#!"  data-num="1"><span>|<</span></a>';
                        str += '<a href="#!"  data-num="' + (currentPage - 1) + '"><span><<</span></a>';
                    } else {
                        //如果是第一页,禁用上一页按钮
                        str += '<span>|<</span>';
                        str += '<span><<</span>';
                    }
                    //中间页码
                    for (var i = rangeStart; i <= rangeEnd; i++) {
                        //如果是当前页的话,就禁用当前页的按钮
                    if (i == currentPage) {
                        str += '<span class="on">' + i + "</span>";
                    } else {
                        //否则就可以点击该页
                        str += '<a href="#"  data-num="' + i + '"><span>' + i + "</span></a>";
                    }
                    }
                    //当前页不是总页,即是最后一页
                    if (currentPage != totalPage) {
                        str += '<a href="#"  data-num="' + (currentPage + 1) + '"><span>>></span></a>';
                        str += '<a href="#"  data-num="' + totalPage + '"><span>>|</span></a>';
                    } else {
                        //如果是最后页,禁用下一页
                        str += '<span>>></span>';
                        str += '<span>>|</span>';
                    }
                }
                                                    
                str += ' 一共' + totalPage + '页, ' + totalCount + '条记录 </div>';
                
                var divpager = document.getElementById("pager");
                divpager.innerHTML = str;
                //获取所有生成的页面链接
                var listTag = divpager.getElementsByTagName('a');
                //绑定li事件
                for (var i = 0; i < listTag.length; i++) {
                    listTag[i].onclick = function() {
                        var currentPage = this.getAttribute('data-num');
                        nowcurrentPage(currentPage);
                        return false;
                    };
                }
            }
            //传递页面
            function nowcurrentPage(currentPage) {
                this.currentPage = currentPage;
                initPage();
            }
            
            //生成每页的数据
            function pageCon(arr, rangeStartitem, len) {
                var constr = '';
                for (var i = rangeStartitem; i < rangeStartitem + len; i++) {
                    constr += "<li>"+ arr[i] + "</li>";
                }
                return constr;
            }
        </script>
</body>
</html>

2.后端实现

端实现可以拼sql,但是在实际开发中多用插件,比如pageHelper,当然也可以自己写基于拦截器的Mybatis分页插件。

PageHelper插件的主要功能就是开发者不需要每个POJO类的增删改查里都包括相关方法了,它帮你做了。开发者只需要有一个selectAll的方法,它会根据你使用的数据库来将你selectAll的sql改装成一个分页查询的sql,并顺带生成一个查询总数的sql。对应不同的数据库有不同的方言,如常见的Mysql,分页关键字是limit,它就是这样组装成需要的sql。

@Override  
    public String getPageSql(String sql, Page page, CacheKey pageKey) {  
        StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14);  
        sqlBuilder.append(sql);  
        if (page.getStartRow() == 0) {  
            sqlBuilder.append(" LIMIT ");  
            sqlBuilder.append(page.getPageSize());  
        } else {  
            sqlBuilder.append(" LIMIT ");  
            sqlBuilder.append(page.getStartRow());  
            sqlBuilder.append(",");  
            sqlBuilder.append(page.getPageSize());  
            pageKey.update(page.getStartRow());  
        }  
        pageKey.update(page.getPageSize());  
        return sqlBuilder.toString();  
    }  

PageHelper不仅帮你分页查询了数据,在返回时直接返回Page对象,里更是封装了许多分页信息。但是在前后台json数据交互时,由于Page对象继承自ArrayList,json不会保留其分页信息,所以在使用时往往是这样使用的:

@Override  
    public PageInfo<TopicPost> selectAllPublicTopicPost(int pageNum) {  
        int pageSize = 10;  
        PageInfo<TopicPost> topicPostList = new PageInfo<TopicPost>();//主题帖表  
        try {  
            PageHelper.startPage(pageNum, pageSize);  
            topicPostList =  ((Page<TopicPost>)topicPostDao.daoSelectAllPublicTopicPost()).toPageInfo();  
        } catch (Exception e) {  
            log.error("查询状态正常的主题帖失败!"+e.toString());  
            e.printStackTrace();  
        }  
        return topicPostList;  
    }  
即将查询出来的Page转为PageInfo(没有继承ArrayList),将你的PageInfo<Object>返回给前台就可以了。


通过上述例子,我们可以看到PageHelper的优缺点。

优点:封装分页sql,使我们不需要每个地方都去写分页的查询语句;同时,使我们select的sql语句向下兼容,换了数据库也不需要更改sql代码;

缺点:自带的Page对象转json时会丢失分页数据;而转为PageInfo对象时分页信息过多(这一点作者已在github上说明,建议自己实现PageInfo)

总结:实际的项目中,还是后端进行分页为好,不要使用前端分页,因为前端分页基本是一次性把所有数据获取下来,然后前端才开始进行分页,导致页面性能下降(客户端需要花时间处理),所以建议还是用后端处理分页,前端发送ajax请求获取数据(按需加载)。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值