分页查询就是把查询返回的记录进行分页显示。例如,可以把查询返回的100条记录分成10页,每页显示10条记录,用户可以选择不同页码查看对应页的记录,方便了用户对记录的查看和操作。
分页查询还可以提高查询效率,分页查询仅返回当前页显示的记录,不会返回全部记录,既节省内存又提高了数据传输效率。
在com.eshop.util包下新建PagerTag类,该类继承TagSupport类。代码如下:
/**
* @Title: PagerTag.java
* @Package com.eshop.util
* @Description: 分页类文件
* @author xinch
* @date 2019年8月2日
* @version V1.0
*/
package com.eshop.util;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
/**
* @ClassName: PagerTag
* @Description: 分页类,自定义分页标签
* @author xinch
* @date 2019年8月2日
*
*/
public class PagerTag<T> extends TagSupport {
private static final long serialVersionUID = 5729832874890369508L;
/**
* @Fields field:field:对象记录结果集
*/
private List<T> list;
/**
* @Fields field:获取分页记录的action
*/
protected String url;
/**
* @Fields field:field:页容量
*/
protected int pageSize = 10;
/**
* @Fields field:field:当前页
*/
protected int pageNo = 1;
/**
* @Fields field:field:总记录数
*/
protected int recordCount;
/**
* @Fields field:field:开始记录数
*/
protected int lastMax;
/**
* <p>Title: doStartTag</p>
* <p>Description: </p>
* @return
* @throws JspException
*/
@SuppressWarnings("rawtypes")
public int doStartTag() throws JspException {
//总页数
int pageCount = (this.recordCount + this.pageSize - 1) / this.pageSize;
StringBuilder sb = new StringBuilder();
sb.append(" <div class=\"pagin\">");
if (this.recordCount == 0) {
sb.append("<strong>没有可显示的项目</strong>\r\n");
} else {
if (this.pageNo > pageCount)
this.pageNo = pageCount;
if (this.pageNo < 1)
this.pageNo = 1;
sb.append("<form method=\"post\" action=\"").append(this.url)
.append("\" name=\"qPagerForm\">\r\n");
HttpServletRequest request = (HttpServletRequest) this.pageContext
.getRequest();
Enumeration enumeration = request.getParameterNames();
String name = null;
String value = null;
while (enumeration.hasMoreElements()) {
name = (String) enumeration.nextElement();
value = request.getParameter(name);
if (name.equals("pageNo")) {
if ((value != null) && (!"".equals(value))) {
this.pageNo = Integer.parseInt(value);
}
} else {
sb.append("<input type=\"hidden\" name=\"").append(name)
.append("\" value=\"").append(value).append(
"\"/>\r\n");
}
}
sb.append("<input type=\"hidden\" name=\"").append("pageNo")
.append("\" value=\"").append(this.pageNo).append(
"\"/>\r\n");
sb.append(" 共<strong>").append(this.recordCount).append(
"</strong>条记录").append(" ,共<strong>").append(pageCount).append(
"</strong>页").append(",当前显示第<strong>").append(pageNo).append(
"</strong>页 \r\n");
sb.append("<ul class=\"paginList\">");
if (this.pageNo == 1)
sb.append("<li class=\"paginItem\"><a href=\"javascript:;\"><span class=\"pagepre\"> </span>").append(
"</a></li>\r\n");
else {
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(").append(
this.pageNo - 1).append(")\"><span class=\"pagepre\"> </span></a></li>\r\n");
}
int start = 1;
if (this.pageNo > 4) {
start = this.pageNo - 1;
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(1)\">1</a></li>\r\n");
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(2)\">2</a></li>\r\n");
sb.append("<li class=\"paginItem more\"><a href=\"javascript:;\">...</a></li>\r\n");
}
int end = this.pageNo + 1;
if (end > pageCount) {
end = pageCount;
}
for (int i = start; i <= end; i++) {
if (this.pageNo == i)
sb.append("<li class=\"paginItem current\"><a href=\"javascript:;\"><span class=\"current\">").append(i).append(
"</span></a></li>\r\n");
else {
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(").append(i)
.append(")\">").append(i).append("</a></li>\r\n");
}
}
if (end < pageCount - 2) {
sb.append("<li class=\"paginItem more\"><a href=\"javascript:;\">...</a></li>\r\n");
}
if (end < pageCount - 1) {
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(").append(
pageCount - 1).append(")\">").append(pageCount - 1)
.append("</a></li>\r\n");
}
if (end < pageCount) {
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(").append(
pageCount).append(")\">").append(pageCount).append(
"</a></li>\r\n");
}
if (this.pageNo == pageCount)
sb.append("<li class=\"paginItem\"><a href=\"javascript:;\"><span class=\"pagenxt\"> ").append(
"</span></a></li>\r\n");
else {
sb.append("<li class=\"paginItem\"><a href=\"javascript:turnOverPage(").append(
this.pageNo + 1).append(")\"><span class=\"pagenxt\"> </a></li>\r\n");
}
sb.append("</ul></form>\r\n");
sb.append("<div class=\"clr\"></div>");
sb.append("<script language=\"javascript\">\r\n");
sb.append(" function turnOverPage(no){\r\n");
sb.append(" if(no>").append(pageCount).append("){");
sb.append(" no=").append(pageCount).append(";}\r\n");
sb.append(" if(no<1){no=1;}\r\n");
sb.append(" document.qPagerForm.pageNo.value=no;\r\n");
sb.append(" document.qPagerForm.submit();\r\n");
sb.append(" }\r\n");
sb.append("</script>\r\n");
}
sb.append("</div>\r\n");
try {
this.pageContext.getOut().println(sb.toString());
} catch (IOException e) {
throw new JspException(e);
}
return 0;
}
public Integer getLastMax()
{
this.lastMax = (getPageNo() - 1) * getPageSize();
return this.lastMax;
}
public void setLastMax(Integer num)
{
this.lastMax = num;
}
public void setUrl(String url) {
this.url = url;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public void setRecordCount(int recordCount) {
this.recordCount = recordCount;
}
public String getUrl() {
return url;
}
public int getPageSize() {
return pageSize;
}
public int getPageNo() {
return pageNo;
}
public int getRecordCount() {
return recordCount;
}
@SuppressWarnings("rawtypes")
public List getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}PagerTag类继承了TagSupport类,TagSupport类是自定义JSP标签类的基类,它实现了标签和迭代标签接口。
PagerTag是泛型类。在定义一个泛型的时候,在<>之间定义形式类型参数,例如,“class PagerTag<T>”,其中T不代表值,而是表示数据类型。使用具有泛型定义的类,在外部实例化该类时,需要传入实际的类型参数用于指定该类所使用的数据类型,因此PagerTag可以传入任何数据类型。
PagerTag的list属性是List集合类型,它用于存储传入的记录集合,传入的记录为引用类型或其它数据类型。PagerTag类的url属性描述了获取分页记录的action路径,pageSize属性描述了每页显示的记录数,pageNo属性描述了当前显示的页数,recordCount属性描述了总记录数量,lastMax属性描述了当前页开始的记录数。PagerTag类的属性值都可以由在JSP页面中定义的PagerTag标签传入。
JSP页面在服务端执行时遇到自定义标签,会调用自定义标签类的doStartTag方法进行标签的初始化。PagerTag类的doStartTag方法完成两类工作:一类工作是调用url指向的action从服务器端获取查询记录;一类工作是动态创建HTML元素和生成查询表单。
建立pager.tld文件
paper.tld文件用于定义分页所需要的标签,pager.tld是一个XML文件,但扩展名是tld。我们需要创建pager.tld文件,并将该文件保存到WEB-INF的tld目录下,如果WEB-INF下没有tld目录,需要创建tld目录。pager.tld文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <taglib version="2.0" 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 web-jsptaglibrary_2_0.xsd"> <tlib-version>5.0</tlib-version> <short-name>myTag</short-name> <uri>http://hi.csdn.net/tjcyjd/tags</uri> <!-- 自定义标签的描述信息 --> <tag> <!-- 标签名 --> <name>pager</name> <!-- 对应的标签处理类全限定名 --> <tag-class>com.hgzp.ebook.util.PagerTag</tag-class> <!-- 标签主体的类型 --> <body-content>empty</body-content> <!-- 当前页号属性的描述信息 --> <attribute> <!-- 属性名 --> <name>pageNo</name> <!-- 该属性是否为必要的 --> <required>true</required> <!-- 属性值是否可以在JSP运行时期动态产生 --> <rtexprvalue>true</rtexprvalue> <!-- 属性的数据类型 --> <type>int</type> </attribute> <!-- 总记录数属性的描述信息 --> <attribute> <name>recordCount</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <type>int</type> </attribute> <!-- 总页数属性的描述信息 --> <attribute> <name>pageSize</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <type>int</type> </attribute> <!-- 分页标签要跳转的URI属性的描述信息 --> <attribute> <name>url</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <type>java.lang.String</type> </attribute> </tag> </taglib>
也可以直接下载pager.tld文件。
下载地址:www.milihua.com/download/pager.tld
给分页标签添加样式
PagerTag类的doStartTag方法动态创建HTML元素和生成查询表单时使用了CSS样式,编辑css目录下的common.css文件,在文件后面添加下面的样式:
/*查询页分页样式*/
.pagin{position:relative;width:100%; margin-top:10px; height:30px; overflow:hidden;color:#a0a0a0;line-height:30px;}
.pagin .blue{color:#a0a0a0;font-style:normal;}
.pagin .paginList{position:absolute;right:0px;top:0; overflow:hidden; margin-top:0;}
.pagin .paginList .paginItem{float:left;}
.pagin .paginList .paginItem a{float:left; width:31px; padding-right:8px;padding-left:8px; height:28px;border:1px solid #DDD; text-align:center;line-height:30px;border-left:none;color:#3399d5;}
.pagin .paginList .paginItem:first-child a{border-left:1px solid #DDD;}
.pagin .paginList .paginItem:first-child a{border-bottom-left-radius:5px;border-top-left-radius:5px;}
.pagin .paginList .paginItem:last-child a{border-bottom-right-radius:5px;border-top-right-radius:5px;}
.pagin .paginList .paginItem.current,.pagin .paginList .paginItem.current a{background:#f5f5f5; cursor:default;color:#a0a0a0;}
.pagin .paginList .paginItem:hover{background:#f5f5f5;}
.pagin .paginList .paginItem.more,.pagin .paginList .paginItem.more a:hover{ cursor:default;}
.pagin .paginList .paginItem.more:hover{background:#FFF;}
.pagin .paginList .paginItem.more a{color:#737373;}
.pagepre{background:url(../projectimage/pre.gif) no-repeat center center; width:31px; height:28px;}
.pagenxt{background:url(../projectimage/next.gif) no-repeat center center; width:31px; height:28px;}
.pagin form{height:30px; overflow:hidden;}至此,添加分页标签工作已经完成。