住javaWeb分页实现(模拟百度首页)

本文来源于 http://blog.csdn.net/tjpu_lin/article/details/41050475

近期在开发一个项目,项目中有非常多数据展示的模块。所以要用到分页,网上搜了非常多分页的样例,可是非常多实现的方法和自身的代码实例耦合度太高。导致直接拿来用根本不行。

于是自己仅仅能亲自上阵了,关于分页实现大体逻辑是前台须要和后台相互传递页面參数(比如当前页面,页面大小。总共页数等),后台主要接受前台穿过来的pageNum(当前页码),进行数据查询,然后查完数据后返回给前台的同一时候也要将页面返回给前台。好让前台结合CSS在分页样式中高亮显示出当前页。

步骤大体能够分为下面几步。

1.后台sql查询数据时(底层我用的是Mysql数据库)

前台仅仅须要传递一个pageNum,然后后台定义个页面大小的常量吧,我是定义到Constant类里面。作为一个常量来使用的。

  /**
     * 分页页面參数
     */
    public static final Integer PAGESIZE = 10;

使用的时候用Constant.PAGESIZE来调用。

这时候我们须要了解mysql分页的sql的实现是这种:

在mysql中,我们用limit来实现分页数据的查询,limit A,B 表示从A開始,往后取B个数。

对于我们来说,第一页就是0-9这10条记录(mysql记录的索引是从0開始的)。所以我们第一页取的数据相应的sql是 limit 0,10。以此类推第二页是  limit 10,10,第三页是 limit  20,10  ......

開始的索引值须要我们进行一个简单的计算。Integer startIndex = (pageNum-1)*10,,不理解的将pageNum值代入想一想就知道了。

limit startIndex 。PAGESIZE始终都是放在查询的最后面。即前面什么各种where 。group by, order by所有写好后再接limit

2.后台pageVo类的构建

由于前台须要后台的数据比較多,所以我们将它们封装到一个pageVo对象里面。

以下是我pageVo类的定义

package com.bada.core.vo;

import java.io.Serializable;
import java.util.Map;

/**
 * @author Kevin
 * 用于分页的类
 */
public class PageVo implements Serializable {
	private int curPage;//当前页
	private int pageSize;//每页的大小
	private int totalRows;//总记录数
	private int totalPages;//总页数
    private String queryCondition; //查询条件(字符串),用户将查询条件穿到前台然后再传回来
    private Map<String,Object> queryConditions; //查询条件,针对多条件

    public Map<String, Object> getQueryConditions() {
        return queryConditions;
    }
    public void setQueryConditions(Map<String, Object> queryConditions) {
        this.queryConditions = queryConditions;
    }
    public int getCurPage() {
		return curPage;
	}
	public void setCurPage(int curPage) {
		this.curPage = curPage;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getTotalRows() {
		return totalRows;
	}
	public void setTotalRows(int totalRows) {
		this.totalRows = totalRows;
	}
	public int getTotalPages() {
		return totalPages;
	}
	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}
    public String getQueryCondition() {
        return queryCondition;
    }
    public void setQueryCondition(String queryCondition) {
        this.queryCondition = queryCondition;
    }

    @Override
    public String toString() {
        return "PageVo{" +
                "curPage=" + curPage +
                ", pageSize=" + pageSize +
                ", totalRows=" + totalRows +
                ", totalPages=" + totalPages +
                ", queryCondition='" + queryCondition + '\'' +
                ", queryConditions=" + queryConditions +
                '}';
    }
}

当中加的queryCondition和queryConditions变量是关于带查询条件的页面分页时存入查询条件,传到前台,然后点击下一页时传到后台时不会由于缺失查询条件而载入出的数据位空了。

后台须要new一个PageVo的对象出来。然后set相应的參数值,curPage就是pageNum,pageSize是页面大小。这里要注意的事。在进行数据查询后,还须要对满足条件的全部记录做一个计数,去获取总数值。一般 select count(ID) from ** where **=**, 一般不要count(*),查询效率会低非常多的,count(0)就能够了。当然count(主键)会更快,由于主键是加了索引的。

totalRows相应刚才查询出来的总数。totalPages也是须要我们去计数的。思考一下。一共须要的页面数。我们先弄几个样例来推敲一下,假设有40条记录,依据1页是10条记录,那么就是4页。假设有38条记录,也是4页。事实上就是一个总数除以页面大小向上取整。我们写一个方法去实现。

public class FormatUtils {
    /**
     * 向上取整    比如: 30条数据。每页8条  一共4页
     * @param total
     * @param pageSize
     * @return
     */
    public static int getPageTotal(int total,int pageSize){
        if(pageSize == 0){//分母不能为0
            return 0;
        }
        return (int)Math.ceil((double)total/pageSize);
    }
}

java自带了Math.ceil用来取大于或等于某个数的最小整数。

假设有一个查询条件就set到queryCondition中去,假设有多个就封装到map再set到queryCondtions里面去、详细前台怎么取在后面诉述、

3.前台jstl构建页面元素。

開始是写在页面上一大串jstl代码来生成html代码,后来直接封装到自己定义标签中要方便的多。先展示一下jstl是怎样写的。

<div class="page mg-auto">
<ul class="pagination">
            <c:if test="${pageVo.totalPages > 0}">
                <li><a href="javascript:onSelectPage(${pageVo.curPage - 1})">«</a></li>
                <c:if test="${pageVo.totalPages <= 10}">
                    <c:forEach var="i" begin="1" end="${pageVo.totalPages}">
                        <c:choose>
                            <c:when test="${i == pageVo.curPage}">
                                <li class="active"><a href="javascript:onSelectPage(${i})">${i}</a></li>
                            </c:when>
                            <c:otherwise>
                                <li><a href="javascript:onSelectPage(${i})">${i}</a></li>
                            </c:otherwise>
                        </c:choose>
                    </c:forEach>
                </c:if>
                <c:if test="${pageVo.totalPages > 10}">
                    <c:if test="${pageVo.curPage < 10}">
                        <c:forEach var="i" begin="1" end="10">
                            <c:choose>
                                <c:when test="${i == pageVo.curPage}">
                                    <li class="active"><a href="javascript:onSelectPage(${i})">${i}</a></li>
                                </c:when>
                                <c:otherwise>
                                    <li><a href="javascript:onSelectPage(${i})">${i}</a></li>
                                </c:otherwise>
                            </c:choose>
                        </c:forEach>
                    </c:if>
                    <c:if test="${pageVo.curPage >= 10}">
                        <c:forEach var="j" begin="${pageVo.curPage-5}" end="${pageVo.curPage+4}">
                            <c:if test="${j <= pageVo.totalPages}">
                                <c:choose>
                                    <c:when test="${j == pageVo.curPage}">
                                        <li class="active"><a href="javascript:onSelectPage(${j})">${j}</a></li>
                                    </c:when>
                                    <c:otherwise>
                                        <li><a href="javascript:onSelectPage(${j})">${j}</a></li>
                                    </c:otherwise>
                                </c:choose>
                            </c:if>
                        </c:forEach>
                    </c:if>
                </c:if>
                <li><a href="javascript:onSelectPage(${pageVo.curPage + 1})">»</a></li>
            </c:if>
</ul>
</div>

后来才发现上面的代码事实上能够用自己定义标签实现,页面上一行代码就搞定。重用性高多了~  后面讲这个!

详细的实现逻辑是模仿百度分页的走的,

须要分析的逻辑例如以下(步步递进):

1、一条记录都没有,不显示页码。   推断pageVo的totalPages是否大于0。假设大于0,才去生成分页样式

2、假设总页数小于10,则写一个循环,从1開始。循环到总页数,显示N页(N为totalPages),显示这N页的同一时候,依据pageVo里面的curPage推断哪一页须要高亮显示出来。

3、假设总页数大于10,小于10的部分显示效果如上。大于10的时候,高亮页面始终在中间区域,即以当前页curPage做为条件。它的左边显示5个,右边显示4个。(详细效果能够看看百度搜索完结果的最下方)

一次性最多展示10页。然后高亮显示在中间(页面大于10)。

每个a标签都要加js函数。当点击的时候跳到以下的函数里面。

<c:if test="${!empty pageVo}"> <%--防止首次进入该页面时没有pageVo而出js错误--%>
    <script type="text/javascript">
        function onSelectPage(curPage){
            if(curPage>=1 && curPage<=${pageVo.totalPages}){
                if (curPage != ${pageVo.curPage}) { //当前页点击禁用跳转
                         window.location.href="${pageContext.request.contextPath}/customer/queryAllSalesShippers?pageNum="+curPage;
                }
            }
        }
    </script>
</c:if>

假设带查询条件的这么去写

window.location.href="${pageContext.request.contextPath}/customer/querySalesShipperCustomer?condition=${pageVo.queryCondition}&pageNum="+curPage;

当然window.location.href=""后面的连接写你查询数据的那个action路径。

关于相应的前端样式是前端去写的,仅仅要有带高亮样式的分页的html代码即可,这里我也贴出css代码好了。

详细样子

/*------------------------------分页 tag defines-------------------------------*/
.page{width:80%;text-align:center;margin-top:80px;}
.pagination {
display: inline-block;
padding-left: 0;
margin: 20px 0;
border-radius: 2px;}
.pagination>li {
display: inline;
}
:before, :after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
:before, :after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.pagination>li:first-child>a, .pagination>li:first-child>span {
margin-left: 0;
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
.pagination>li>a, .pagination>li>span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #428bca;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
}
a {
text-decoration: none;
}
a {
background: 0 0;
}
.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {
color: #fff;
cursor: default;
background-color: #428bca;
border-color: #428bca;
}
.pagination>li>a:hover, .pagination>li>span:hover, .pagination>li>a:focus, .pagination>li>span:focus {
color: #2a6496;
background-color: #eee;
border-color: #ddd;
}
.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {
color: #fff;
cursor: default;
background-color: #428bca;
border-color: #428bca;
}
.pagination>li>a, .pagination>li>span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #428bca;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
}

我写的分页,简单步骤就是3步。后台pageVo构建,前台jstl生成分页模块。然后加个js函数去进行跳转查询

=========================================================我是切割线========================================================

以下说一下关于自己定义标签的实现

详细的思路就是用java代码去将html代码打印出来。就跟servlet用输出流打印页面一样。

1.构建自己定义标签类

package com.bada.biz.service;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import com.bada.core.vo.PageVo;

/**
 * Created by Kevin on 2014/11/2.
 * pageVo的自己定义标签类
 */
public class PageVoTag extends TagSupport {

    private PageVo pageVo;

    @Override
    public int doStartTag() throws JspException {
        try {
            JspWriter out = this.pageContext.getOut();
            if(pageVo == null) {
                return SKIP_BODY;
            }
            if (pageVo.getTotalPages() > 0) {
                out.println("<li><a href=\"javascript:onSelectPage("+(pageVo.getCurPage()-1)+")\">«</a></li>");
                if (pageVo.getTotalPages() <= 10) {
                    for (int i = 1; i <= pageVo.getTotalPages(); i++) {
                        if (i == pageVo.getCurPage()) {
                            out.println("<li class=\"active\"><a href=\"javascript:onSelectPage("+i+")\">"+i+"</a></li>");
                        } else {
                            out.println("<li><a href=\"javascript:onSelectPage("+i+")\">"+i+"</a></li>");
                        }
                    }
                }

                if (pageVo.getTotalPages() > 10) {
                    if (pageVo.getCurPage() < 10) {
                        for (int i = 1; i <= 10; i++) {
                            if (i == pageVo.getCurPage()) {
                                out.println("<li class=\"current\"><a href=\"javascript:onSelectPage("+i+")\">"+i+"</a></li>");
                            } else {
                                out.println("<li><a href=\"javascript:onSelectPage("+i+")\">"+i+"</a></li>");
                            }
                        }
                    }
                    if (pageVo.getCurPage() >= 10) {
                        for (int j = pageVo.getCurPage()-5;j <= pageVo.getCurPage()+4; j++) {
                            if (j <= pageVo.getTotalPages()) {
                                if (j == pageVo.getCurPage()){
                                    out.println("<li class=\"current\"><a href=\"javascript:onSelectPage("+j+")\">"+j+"</a></li>");
                                } else {
                                    out.println("<li><a href=\"javascript:onSelectPage("+j+")\">"+j+"</a></li>");
                                }
                            }
                        }
                    }
                }
                out.println("<li><a href=\"javascript:onSelectPage("+(pageVo.getCurPage()+1)+")\">»</a></li>");
            }

        } catch(Exception e) {
            throw new JspException(e.getMessage());
        }
        return SKIP_BODY;
    }

    @Override
    public int doEndTag() throws JspException {
        return EVAL_PAGE;
    }

    @Override
    public void release() {
        super.release();
        this.pageVo = null;
    }

    public PageVo getPageVo() {
        return pageVo;
    }

    public void setPageVo(PageVo pageVo) {
        this.pageVo = pageVo;
    }
}

能够看到。代码明显比jstl少非常多。看来还是ava代码好使哇。这个类可能须要下载相应的jar包,这个自己百度一下。

2.自己定义标签文件    命名为  pageVo.tld

<?xml version="1.0" encoding="UTF-8"?

>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">

    <tlib-version>1.0</tlib-version>
    <short-name>cc</short-name>
    <uri>/pageTaglib</uri>

    <tag>
        <name>showPaging</name>
        <tag-class>com.bada.biz.service.PageVoTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>pageVo</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

</taglib>

里面相应的tag-class就是上面写的那个类,pageVo为传入的參数,到时候前台用${pageVo}赋值这个參数。

3.web.xml里面的配置

    <!--配置自己定义标签-->
    <jsp-config>
        <taglib>
            <taglib-uri>/pageTaglib</taglib-uri>
            <taglib-location>/WEB-INF/tld/pageVo.tld</taglib-location>
        </taglib>
    </jsp-config>

加在web-app标签里面一级即可了

4.jsp页面使用

引用标签:uri是上面定义的uri。prefix为前缀名。随意取的

<%@ taglib uri="/pageTaglib" prefix="pv"%>

使用标签

<div class="page mg-auto">
            <ul class="pagination">
                <pv:showPaging pageVo="${pageVo}" />
            </ul>
        </div>

一行代码搞定。。再也不用不停copy 那一大串jstl代码了。

至此 分页模块搞定了,相关文件下载http://download.csdn.net/detail/tro_picana/8151805

版权声明:本文博主原创文章。博客,未经同意不得转载。

时间: 2024-12-17 07:50:27

住javaWeb分页实现(模拟百度首页)的相关文章

模拟百度分页算法实现

定义变量 pageSize 每一页显示的记录条件 pageNow 当前页,初始默认值为1 pageCount 总页数,有pageSize和数据库总记录数决定 公式:double res = select count(id) from 记录表 // 使用Math函数将结果向上取整 pageCount = (int) Math.ceil(res / pageSize); pageNow是传入参数,pageCount是传出参数,pageSize内部使用页码分页显示 pageNum 每一页显示的页码数,

C#模拟百度登录并到指定网站评论回帖(一)

核心信息: 请求网址:  https://passport.baidu.com/v2/api/?login请求方法:  POST状态码:  HTTP/1.1 200 OK请求头 //用户代理 UserAgent,是指浏览器,它的信息包括硬件平台.系统软件.应用软件和用户个人偏好.在X.400电子系统中,用户代理是一种对数据打包.创造分组头,以及编址.传递消息的部件.用户代理并不是仅指浏览器,还包括搜索引擎. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW

Webbrowser模拟百度一下子点击事件

Webbrowser模拟百度一下点击事件新建一个form,有一个button和一个webbrowser控件.然后webbrowser一开始加载的就是百度主页.然后在文本框里输入点东西,如何做到点击button就相当于点击点击webbrowser中的"百度一下"按钮? 分享到: ------解决方案--------------------refer: ? 1 2 3 4 5 6 7 8 9 10 11     private void Form1_Load(object sender, 

python模拟百度登陆

本文原地址 目录 说明 环境准备 登陆过程分析 登陆过程完整代码 有效性测试 说明 本文做的是百度二维码扫码登陆,至于为什么要做扫码登陆,主要是因为:1,用账号密码登陆时,在测试过程中,如果清除cookie,会弹出验证码,这个倒是无所谓,要命的是在登陆过程中有可能出发百度的账号保护机制,就算输入验证码,百度还会强制要求手机短信进行二次验证,这个触发机制目前还不明确. 准备环境 准备python3环境以及安装requests类库,chorme浏览器.关于requests类库的基本用法可参考链接:爬

如何邀请好友注册您的网站(模拟百度网盘)

花了一年时间做了个网盘下载站点,有兴趣的朋友可以看看站名:去转盘网 其中有个需求是想模拟百度网盘的邀请好友注册功能,想了很久果然 "皇天不负有心人" ,终于整理出个思路,并且附上代码,希望各位网友多多吐槽.我的思路大体是用网络范围内唯一的字符串uuid为标识去邀请好友,邀请者给个状态位 1 代表邀请者,并给他绑定个唯一uuid.被邀请者给个标识位0 代表被邀请者,如果他注册成功,则可以根据邀请链接获得uuid去查询数据库找到邀请者,找到后给予相应积分即可,代码如下: public St

java爬取百度首页源代码

爬虫感觉挺有意思的,写一个最简单的抓取百度首页html代码的程序.虽然简单了一点,后期会加深的. 1 package test; 2 3 import java.io.BufferedReader; 4 import java.io.InputStreamReader; 5 import java.net.URL; 6 import java.net.URLConnection; 7 8 public class Main 9 { 10 public static void main(Strin

模拟百度搜索框,输入时显示历史记录

今天写了个小demo,利用本地存储的特点,模拟百度搜索框. 主要知识是利用本地存储的特点,模拟百度搜索时的历史记录显示. 主要HTML代码为 <div class="search"> <input type="text"/> <button class="btn">搜索</button> </div> <ul class="hidden"> <li&

Html5开发——html+css基础一(百度首页)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>百度</title> <style type="text/css"> *{margin: 0;padding: 0;} body{text-align: center;} .header{text-align: right;f

用表格制作百度首页

前一天学习了<table>和一系列的小指令用来制作表格,然后老师布置了制作百度首页的任务,看上去像是很简单结果还是弄了一天的时间,好在最后知道了错误修改的还算美观. 制作很简单,就是小细节上的东西容易出错,所以刚开始学一定要养成有了开头接着写结尾的好习惯. 最上面的一行导航栏还算简单,做好表格大小分配好百分比,剩下的超链接什么的都是再简单不过的内容了. 百度的logo和百度一下这一行起初是规划在了一个表格内,怎么调试都没办法弄好,早上尝试了把他们两个分成了两个表格就简单多了. 个人觉得最头疼的