项目中经常会遇到列表分页的问题,如下图所示:
JSTL的可以帮助我们实现这样的功能,直接上代码吧,如果有不明白的再继续探讨。。。
整个项目的目录结构如下:
我们在WEB-INF目录 新建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>0.9</tlib-version>
<!--标签头-->
<short-name>w</short-name>
<!--将来在页面用taglib引用时的uri属性,这部分的名字可以随便写,只要是符合HTTP网址形式的 -->
<uri>http://www.chinasofti.com/pager/core</uri>
<!-- 自定义标签的描述信息 -->
<tag>
<!-- 标签名 -->
<name>pager</name>
<!-- 对应的标签处理类全限定名 -->
<tag-class>com.bawei.demo.tag.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>
实体类VO
package com.bawei.demo.vo;
import java.io.Serializable;
/**
* @author shenyiya
* 1.学号
* 2.用户名 密码 性别 学院 专业名称 研究方向 学生类别 入学日期 学位类型
*/
public class User {
private int id;
private String no; //学号
private String username; //用户名
private String password; //密码
private String sex; //性别
private String dept; //学院
private String majorName; // 专业名称
private String studentCatagory; //学生类别
private String entranceDate; //入学日期
private String degreeType; //学位类型
private String degreePaperTitle; //学位论文题目
private String studyDirection; //研究方向
private String guideTeacher; //指导老师
public String getDegreePaperTitle() {
return degreePaperTitle;
}
public void setDegreePaperTitle(String degreePaperTitle) {
this.degreePaperTitle = degreePaperTitle;
}
public String getStudyDirection() {
return studyDirection;
}
public void setStudyDirection(String studyDirection) {
this.studyDirection = studyDirection;
}
public String getGuideTeacher() {
return guideTeacher;
}
public void setGuideTeacher(String guideTeacher) {
this.guideTeacher = guideTeacher;
}
public String getDegreeType() {
return degreeType;
}
public void setDegreeType(String degreeType) {
this.degreeType = degreeType;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String getMajorName() {
return majorName;
}
public void setMajorName(String majorName) {
this.majorName = majorName;
}
public String getStudentCatagory() {
return studentCatagory;
}
public void setStudentCatagory(String studentCatagory) {
this.studentCatagory = studentCatagory;
}
public String getEntranceDate() {
return entranceDate;
}
public void setEntranceDate(String entranceDate) {
this.entranceDate = entranceDate;
}
public String toString1() {
return "Userinfo [id=" + id + ", no=" + no + ", username=" + username
+ ", password=" + password + ", sex=" + sex + ", dept=" + dept
+ ", majorName=" + majorName + ", studentCatagory="
+ studentCatagory + ", entranceDate=" + entranceDate
+ ", degreeType=" + degreeType + ", degreePaperTitle="
+ degreePaperTitle + ", studyDirection=" + studyDirection
+ ", guideTeacher=" + guideTeacher + "]";
}
}
util包下的Model类
package com.bawei.demo.util;
import java.util.List;
/**
* 分页组件(包含当前页结果数据列表和总记录数)
* 注意,它不是持久化实体类
*
*/
public class PageModel<T> {
private int recordCount;
private List<T> datas;
public int getRecordCount() {
return recordCount;
}
public void setRecordCount(int recordCount) {
this.recordCount = recordCount;
}
public List<T> getDatas() {
return datas;
}
public void setDatas(List<T> datas) {
this.datas = datas;
}
}
tag包下的类
package com.bawei.demo.tag;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class PagerTag extends TagSupport {
private String url; // 请求URI
private int pageSize = 5; // 每页要显示的记录数
private int pageNo = 1; // 当前页号
private int recordCount; // 总记录数
@Override
public int doStartTag() throws JspException {
int pageCount = (recordCount + pageSize - 1) / pageSize; // 计算总页数
// 拼写要输出到页面的HTML文本
StringBuilder sb = new StringBuilder();
//分页的css样式
sb.append("<style type=\"text/css\">");
sb.append(".pagination {padding: 5px;float:left;font-size:12px;}");
sb.append(".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;}");
sb.append(".pagination a:hover, .pagination a:active {border: 1px solid #3fac7b;color: #000;text-decoration: none;}");
sb.append(".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #3fac7b;font-weight: bold;background-color: #3fac7b;color: #FFF;}");
sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");
sb.append("</style>\r\n");
//分页导航
sb.append("<div class=\"pagination\">\r\n");
if (recordCount == 0) {
sb.append("<strong>没有可显示的项目</strong>\r\n");
} else {
// 页号越界处理
if (pageNo > pageCount) {
pageNo = pageCount;
}
if (pageNo < 1) {
pageNo = 1;
}
sb.append("<form method=\"post\" action=\"").append(this.url)
.append("\" name=\"qPagerForm\">\r\n");
// 获取请求中的所有参数
HttpServletRequest request = (HttpServletRequest) pageContext
.getRequest();
Enumeration<String> enumeration = request.getParameterNames();
String name = null; // 参数名
String value = null; // 参数值
// 把请求中的所有参数当作隐藏表单域
while (enumeration.hasMoreElements()) {
name = enumeration.nextElement();
value = request.getParameter(name);
// 去除页号
if (name.equals("pageNo")) {
if (null != value && !"".equals(value)) {
pageNo = Integer.parseInt(value);
}
continue;
}
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(pageNo).append("\"/>\r\n");
// 输出统计数据
sb.append(" 共<strong>").append(recordCount)
.append("</strong>项").append(",<strong>").append(pageCount)
.append("</strong>页: \r\n");
// 上一页处理
if (pageNo == 1) {
sb.append("<span class=\"disabled\">« 上一页").append(
"</span>\r\n");
} else {
sb.append("<a href=\"javascript:turnOverPage(")
.append((pageNo - 1))
.append(")\">« 上一页</a>\r\n");
}
// 如果前面页数过多,显示"..."
int start = 1;
if (this.pageNo > 4) {
start = this.pageNo - 1;
sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n");
sb.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n");
sb.append("…\r\n");
}
// 显示当前页附近的页
int end = this.pageNo + 1;
if (end > pageCount) {
end = pageCount;
}
for (int i = start; i <= end; i++) {
if (pageNo == i) { // 当前页号不需要超链接
sb.append("<span class=\"current\">").append(i)
.append("</span>\r\n");
} else {
sb.append("<a href=\"javascript:turnOverPage(").append(i)
.append(")\">").append(i).append("</a>\r\n");
}
}
// 如果后面页数过多,显示"..."
if (end < pageCount - 2) {
sb.append("…\r\n");
}
if (end < pageCount - 1) {
sb.append("<a href=\"javascript:turnOverPage(")
.append(pageCount - 1).append(")\">")
.append(pageCount - 1).append("</a>\r\n");
}
if (end < pageCount) {
sb.append("<a href=\"javascript:turnOverPage(")
.append(pageCount).append(")\">").append(pageCount)
.append("</a>\r\n");
}
// 下一页处理
if (pageNo == pageCount) {
sb.append("<span class=\"disabled\">下一页 »").append(
"</span>\r\n");
} else {
sb.append("<a href=\"javascript:turnOverPage(")
.append((pageNo + 1))
.append(")\">下一页 »</a>\r\n");
}
sb.append("</form>\r\n");
// 生成提交表单的JS
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");
// 把生成的HTML输出到响应中
try {
pageContext.getOut().println(sb.toString());
} catch (IOException e) {
throw new JspException(e);
}
return SKIP_BODY;
}
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;
}
}
dao包下的类
package com.bawei.demo.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.bawei.demo.db.ConnectionFactory;
import com.bawei.demo.db.DBHelper;
import com.bawei.demo.util.PageModel;
import com.bawei.demo.vo.User;
public class UserDAO {
private Connection conn;
private PreparedStatement ps;
private ResultSet rs;
public UserDAO() throws Exception {
// conn = DBHelper.getConn();
conn=ConnectionFactory.getConn();
}
public PageModel<User> findByPager(int pageNo,int pageSize) throws Exception {
PageModel<User> pm=new PageModel<User>();
String sql = "select * from userinfo limit ?,?";
ps = conn.prepareStatement(sql);
ps.setInt(1, (pageNo-1)*pageSize);
ps.setInt(2, pageSize);
rs = ps.executeQuery();
List<User> list = new ArrayList<User>();
while (rs.next()) {
User userinfo=new User();
userinfo.setId(rs.getInt(1));
userinfo.setNo(rs.getString(2));
userinfo.setUsername(rs.getString(3));
userinfo.setPassword(rs.getString(4));
userinfo.setSex(rs.getString(5));
userinfo.setDept(rs.getString(6));
userinfo.setMajorName(rs.getString(7));
userinfo.setStudentCatagory(rs.getString(8));
userinfo.setEntranceDate(rs.getString(9));
userinfo.setDegreeType(rs.getString(10));
userinfo.setDegreePaperTitle(rs.getString(11));
userinfo.setGuideTeacher(rs.getString(12));
userinfo.setStudyDirection(rs.getString(13));
list.add(userinfo);
}
pm.setDatas(list);
pm.setRecordCount(findAllCount());
return pm;
}
public int findAllCount() throws Exception{
String sql="select * from userinfo";
ps=conn.prepareStatement(sql);
rs=ps.executeQuery();
List<Integer> list=new ArrayList<Integer>();
while(rs.next()){
int id=rs.getInt(1);
list.add(id);
}
return list.size();
}
}
连接数据库的类
package com.bawei.demo.db;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
/**
*
* 鏁版嵁搴撹繛鎺ュ伐鍘傜被
*
*/
public class ConnectionFactory {
private static DataSource dss=null;
static{
Properties pr=new Properties();
try {
pr.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));
} catch (IOException e) {
e.printStackTrace();
}
BasicDataSource ds=new BasicDataSource();
ds.setDriverClassName(pr.getProperty("driver_name"));
ds.setUrl(pr.getProperty("url"));
ds.setUsername(pr.getProperty("username"));
ds.setPassword(pr.getProperty("password"));
dss=ds;
}
private ConnectionFactory(){}
public static Connection getConn() throws SQLException{
return dss.getConnection();
}
}
数据库配置文件config.properties文件
#mysql
driver_name=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db
username=root
password=123
项目的下载地址