分页技术:
JSP页面,用来显示数据! 如果数据有1000条,分页显示,每页显示10条,共100页;好处:利于页面布局,且显示的效率高!
使用技术:
jsp+Servlet+c3p0+mySql+DbUtils组件+
3层结构(web层+service层+dao层)
分页流程图:
分页关键点:
1.分页SQL语句;
2.后台处理: dao/service/servlet/JSP
实现步骤:
1.
环境准备
a)
引入jar文件及引入配置文件
i.
数据库驱动包
ii.
C3P0连接池jar文件 及 配置文件
iii.
DbUtis组件:QueryRunner qr = new QueryRuner(dataSouce);
qr.update(sql);
b)
公用类: JdbcUtils.java
2.
先设计:PageBean.java
3.
Dao接口设计/实现: 2个方法
4.
Service/servlet
5.
JSP
项目源码:
分页项目结构:
主要代码设计:
PageBean.java分页实体类
package com.cn.entity;
import java.util.List;
/**
* 每一页数据参数实体
* @author liuzhiyong
*
* @param <T>
*/
public class PageBean<T> {
private int currentPage;//当前页
private int totalPage;//总页数
private int totalDataRows;//数据总行数
private int countPerPage = 4;//每页显示行数,默认显示4行
private List<T> dataList;//分页查询得到的数据集合,注意这里用泛型较好
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getTotalPage() {
//计算总页数
return (totalDataRows % countPerPage == 0)?(totalDataRows/countPerPage):(totalDataRows/countPerPage+1);
}
public int getTotalDataRows() {
return totalDataRows;
}
public void setTotalDataRows(int totalDataRows) {
this.totalDataRows = totalDataRows;
}
public int getCountPerPage() {
return countPerPage;
}
public void setCountPerPage(int countPerPage) {
this.countPerPage = countPerPage;
}
public List<T> getDataList() {
return dataList;
}
public void setDataList(List<T> dataList) {
this.dataList = dataList;
}
}
dao设计
package com.cn.dao.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.cn.dao.PageDao;
import com.cn.entity.PageBean;
import com.cn.entity.User;
import com.cn.utils.JdbcUtils;
public class PageDaoImpl implements PageDao {
//创建DbUtils组件的核心工具类
private QueryRunner qr = JdbcUtils.getQueryRunner();
/**
* 根据传入的参数,封装pageBean所有参数,注意这里可以不用返回PageBean
*/
public void getPageData(PageBean<User> pageBean) {
//获取数据总行数,并封装入pageBean
int totalDataRows = this.getTotalDataRows();
pageBean.setTotalDataRows(totalDataRows);
int countPerPage = pageBean.getCountPerPage();//获取每页返回的行数
/**
* 问题:在jsp页面,如果当前页为首页,再点击上一页报错;如果当前页为末页,再点下一页显示有问题;
* 解决:判断
* 1.如果当前页<=0; 设置当前页为1
* 2.如果当前页>最大页数;设置当前页为最大页数
*
* 注意:jsp页面中也可直接判断,但是页面单纯做显示用较好,少进行逻辑判断为好
*/
if(pageBean.getCurrentPage() <= 0){
pageBean.setCurrentPage(1);//设置当前页为1
}else if(pageBean.getCurrentPage() > pageBean.getTotalPage()){
pageBean.setCurrentPage(pageBean.getTotalPage());//设置当前页为最大页数
}
int currentPage = pageBean.getCurrentPage();//获取当前页
int startIndex = (currentPage-1)*countPerPage;//计算起始行
//sql查询语句
String sql = "select * from users limit ?,?";
//创建存放数据的集合对象
List<User> list = null;
try {
list = qr.query(sql, new BeanListHandler<User>(User.class), startIndex, countPerPage);
//将查询出来的当前页数据放入pageBean
pageBean.setDataList(list);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获取数据总行数
* @return
*/
public int getTotalDataRows(){
//sql语句
String sql = "select count(*) from users";
//返回的数据总行数
try {
Long count = qr.query(sql, new ScalarHandler<Long>());//返回结果的第一行的第一列
return count.intValue();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
service逻辑业务层
package com.cn.service.impl;
import com.cn.dao.PageDao;
import com.cn.dao.impl.PageDaoImpl;
import com.cn.entity.PageBean;
import com.cn.entity.User;
import com.cn.service.PageService;
/**
* 业务逻辑层实现
* @author liuzhiyong
*
*/
public class PageServiceImpl implements PageService {
//创建dao实例
PageDao dao = new PageDaoImpl();
@Override
public void getPageData(PageBean<User> pageBean) {
dao.getPageData(pageBean);
}
}
servlet控制层
package com.cn.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.cn.entity.PageBean;
import com.cn.entity.User;
import com.cn.service.impl.PageServiceImpl;
/**
* 控制层开发
* @author liuzhiyong
*
*/
public class PageServlet extends HttpServlet {
//创建Service实例
private
PageServiceImpl service = new PageServiceImpl();
//跳转资源
private String uri;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//创建PageBean对象,设置当前页参数,传入Service方法参数(PageBean)
PageBean<User> pageBean = new PageBean<User>();
//获取“当前页"参数(第一次访问访问当前页的时候为null)
String currentPage1 = request.getParameter("currentPage");
//判断
if(currentPage1==null || "".equals(currentPage1.trim())){
currentPage1 = "1";//第一次访问时,设置当前页为1
}
//转换为int
int currentPage = Integer.parseInt(currentPage1);
//将当前页封装到pageBean对象中
pageBean.setCurrentPage(currentPage);
//调用业务逻辑获取当前页的数据pageBean
service.getPageData(pageBean);//此时pageBean已经填充了数据
//将pageBean对象数据pageData放入域对象
request.setAttribute("pageBean", pageBean);
//转发到显示页面
uri = "/index.jsp";
} catch (Exception e) {
e.printStackTrace();//测试使用
//出现错误,跳转到错误页面,给用户友好提示
uri = "/error/error.jsp";
}
request.getRequestDispatcher(uri).forward(request, response);
}
}
JdbcUtils工具类
package com.cn.utils;
import org.apache.commons.dbutils.QueryRunner;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils {
/**
* 1.初始化c3p0连接池
*/
private static ComboPooledDataSource ds;
static{
ds = new ComboPooledDataSource();
}
/**
* 2. 创建DbUtils核心工具类对象
*/
public static QueryRunner getQueryRunner(){
/*
* 创建QueryRunner对象,传入连接池对象。在创建QueryRunner对象的时候,
* 如果传入了数据源对象,那么在使用QueryRunner对象方法的时候,就不需要传入连接对象,会自动从数据源中获取连接(不用关闭连接)
*/
return new QueryRunner(ds);
}
}
分页显示页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 引入jstl核心标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<table border="1" cellpadding="5" cellspacing="0" align="center" width="50%">
<tr>
<th>编号</th>
<th>姓名</th>
<th>密码</th>
</tr>
<!-- 迭代数据 -->
<c:choose>
<%-- 判断pageBean中集合不为空和null则迭代集合 --%>
<c:when test="${not empty requestScope.pageBean.dataList }">
<c:forEach items="${requestScope.pageBean.dataList }" var="user">
<tr align="center">
<td>${user.id }</td>
<td>${user.name }</td>
<td>${user.password }</td>
</tr>
</c:forEach>
</c:when>
<%-- 判断pageBean中集合为空 --%>
<c:otherwise>
<tr>
<td colspan="3">对不起,没有您要找的数据</td>
</tr>
</c:otherwise>
</c:choose>
<tr align="center">
<td colspan="3">
当前第${requestScope.pageBean.currentPage }页 共${requestScope.pageBean.totalPage }页
<a href="${pageContext.request.contextPath }/PageServlet?currentPage=1">【首页】</a>
<a href="${pageContext.request.contextPath }/PageServlet?currentPage=${requestScope.pageBean.currentPage-1}">【上一页】</a>
<a href="${pageContext.request.contextPath }/PageServlet?currentPage=${requestScope.pageBean.currentPage+1}">【下一页】</a>
<a href="${pageContext.request.contextPath }/PageServlet?currentPage=${requestScope.pageBean.totalPage}">【末页】</a>
</td>
</tr>
</table>
</body>
</html>