JavaEE的分页方法
来源:互联网 发布:雅思阅读网络课 编辑:程序博客网 时间:2024/06/05 18:47
- 分页基本概述
- 什么是分页查询?
- 将数据按页分配,每一页显示固定数量的数据
- 为什么使用分页查询?
- 利于页面布局,且显示的效率高!!
- 两种分页实现方式:
- 物理分页:
- 使用数据库的分页功能,一次只查询一页数据;
- 逻辑分页:
- 一次查出全部数据,然后由程序控制取出需要的数据;
- 分页关键点
- 分页SQL语句;
- 后台处理: dao/service/servlet/JSP
- 物理分页的功能设计
- PageCustomer分页对象:
- pageIndex(从1开始)
- pageSize(每页多少条数据)
- totalSize(总共多少条)
- totalPage(总共多少页)
- List<Customer>(这页的数据)
- 点击第2页连接,把pageIndex=2发送给Servlet
- Servlet调用service
- service执行分页业务,调用dao
- dao进行数据库分页操作,返回Page分页对象
- 实现步骤
- 环境准备
- 引入jar文件及引入配置文件
- 数据库驱动包
- C3P0连接池jar文件 及 配置文件
- DbUtis组件:
- 公用类: JdbcUtils.java
- 先设计:PageBean.java
- Dao接口设计/实现: 2个方法
- Service/servlet
- JSP
- 示例1
- 表示分页的domain
public classPageCustomer{
private intpageIndex;//第几页
private intpageSize;//每页的数据
private inttotalSize;//一共有多少数据
private inttotalPage;//一共多少页
privateList<Customer>customerList;//查询页的数据
publicPageCustomer(intpageIndex,intpageSize) {
if(pageIndex< 1) {
this.pageIndex=1;
}else{
this.pageIndex=pageIndex;
}
if(pageSize< 1) {
this.pageSize=1;
}else{
this.pageSize=pageSize;
}
}
//get,set略
}
- 分页Servlet
public class PageCustomerServletextends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
response.setContentType("text/html");
try{
int pageIndex= 1;//当前第几页
int pageSize= 10;//每页的数据
String pageIndexStr= request.getParameter("pageIndex");
String pageSizeStr= request.getParameter("pageSize");
//为了程序健壮性和容错性,如果 request.getParameter("pageIndex");
//没有查到数据,那么还有默认值int pageIndex = 1;
//如果查到了数据,就直接用查到的数据,替代默认值
try{
pageIndex= Integer.parseInt(pageIndexStr);
pageSize= Integer.parseInt(pageSizeStr);
}catch(Exception e) {
}
//以当前页和每页的数据构造出一个分页类
PageCustomer pageCustomer=new PageCustomer(pageIndex, pageSize);
//以这个分页类为参数,传递给DAO,获取这个页数的数据集合
ObjectFactory.getCustomerService().page(pageCustomer);
//将页数,和该页的数据个数传递给JSP
request.setAttribute("pageCustomer", pageCustomer);
//将存放有该页面的人员信息集合,传递给JSP端
request.setAttribute("customerList",pageCustomer.getCustomerList());
//数据查询完毕之后,就跳转到分页显示页面
request.getRequestDispatcher("pageCustomer.jsp").forward(request,response);
}catch(Exception e) {
response.getWriter().print("分页查询出错:"+ e.getMessage());
}
}
}
- 工厂类,快速获取Service对象
public class ObjectFactory{
private static DataSource dataSource;
private static CustomerService customerService;
private static CustomerDao customerDao;
static{
dataSource=new ComboPooledDataSource();
customerService=new CustomerService();
customerDao=new CustomerDaoImpl();
}
public static DataSource getDataSource() {
return dataSource;
}
public static CustomerService getCustomerService() {
return customerService;
}
public static CustomerDao getCustomerDao() {
return customerDao;
}
}
- 后台Service
public class CustomerService{
/**
*将Servlet传递来的有关于分页查询的数据传递给DAO
*
*@param pageCustomer
*/
public void page(PageCustomer pageCustomer)throws Exception{
ObjectFactory.getCustomerDao().page(pageCustomer);
}
}
- 接口DAO
public interface CustomerDao{
void page(PageCustomer pageCustomer)throws SQLException;
}
- 实现DAO的实现类
public class CustomerDaoImplimplements CustomerDao{
/**
*根据Servlet传递来的分页数据,在数据库中进行分页查找
*/
public void page(PageCustomer pageCustomer)throws SQLException{
//mysql的分页语法:select * from customer limit begin,size;
//先执行分页语句查询,获取当前页,和该页有多少数据
int begin=(pageCustomer.getPageIndex()- 1)* pageCustomer.getPageSize()+ 1;
QueryRunner run=new QueryRunner(ObjectFactory.getDataSource());
List<Customer> customer= run.query("select * from customer limit ?,?"
,new BeanListHandler<Customer>(Customer.class)
,begin
,pageCustomer.getPageSize());
pageCustomer.setCustomerList(customer);
//使用聚合函数查看一共有多少数据
long totalSize= run.query("select count(*) from customer",new ScalarHandler<Long>());
pageCustomer.setTotalSize((int) totalSize);
/*根据全部的数据来分页.用当前全部数据(totalSize)乘以每页数据(PageSize),来获取需要分多少页
但是除法会舍去余数,所以我们加上一个9,比如我们有99条数据,应该是分10,前9页是每页10条,最后一页是9条
加上一个9就是108条数据,其中9条是空的。这样除以10(也就是每页10条数据),就分了10,舍去了余数8,也就得到了最后一页只有9个数据的效果,每页20条数据就减去19。也就是说,我们的总数据需要加上(PageSize-1)条数据。这里只能加9,结果加8,如果总数据的余数是1,则凑不够一页。如果加10,又多了一页空白页*/
int totalPage=(
pageCustomer.getTotalSize()
+ pageCustomer.getPageSize()
- 1)
/ pageCustomer.getPageSize();
pageCustomer.setTotalPage(totalPage);
}
}
- 实例分页JSP
<div>
<ahref="PageCustomerServlet?pageIndex=1&pageSize=10">首页</a>
<!--分页条,如果当前页数不为1的话才会显示上一页的选项 -->
<c:iftest="${pageCustomer.pageIndex!=1}">
<ahref="PageCustomerServlet?pageIndex=${pageCustomer.pageIndex-1 }&pageSize=10">上一页</a>
</c:if>
<%//根据分页类对分页条动态添加一个页数链接
PageCustomer pageCustomer=(PageCustomer)request.getAttribute("pageCustomer");//获得分页类
int pageIndex=pageCustomer.getPageIndex();//获得当前页
int begin=pageIndex-3;//当前页减去一个数字,就是当前页前面的页数
if(begin<1){//如果前面的页数小于1,就让它等于1
begin=1;
}
int end=pageIndex+2;
if(end>pageCustomer.getTotalPage()){
end=pageCustomer.getTotalPage();
}
//根据开始页和结束页来循环动态添加页数
for(int i=begin;i<=end;i++){
//如果循环到的页数与当前页相等,说明用户正在当前页,就直接输出一个数组,而不是链接
if(i==pageIndex){
out.print(i);
}else{
%>
<ahref="PageCustomerServlet?pageIndex=<%= i%>&pageSize=10"><%= i%></a>
<%
}
}
%>
<c:iftest="${pageCustomer.pageIndex!=pageCustomer.totalPage}">
<ahref="PageCustomerServlet?pageIndex=${pageCustomer.pageIndex+1 }&pageSize=10">下一页</a>
</c:if>
<ahref="PageCustomerServlet?pageIndex=${pageCustomer.totalPage }&pageSize=10">尾页</a>
</div>
</div>
- 示例2
- 工具类
/**
*工具类
* 1.初始化C3P0连接池
* 2.创建DbUtils核心工具类对象
*/
public class JdbcUtils{
/**
* 1.初始化C3P0连接池
*/
private static DataSource dataSource;
static{
dataSource=new ComboPooledDataSource();
}
/**
* 2.创建DbUtils核心工具类对象
*/
public static QueryRunner getQueryRuner(){
//创建QueryRunner对象,传入连接池对象
//在创建QueryRunner对象的时候,如果传入了数据源对象;
//那么在使用QueryRunner对象方法的时候,就不需要传入连接对象;
//会自动从数据源中获取连接(不用关闭连接)
returnnew QueryRunner(dataSource);
}
}
- 封装分页的参数
/**
*封装分页的参数
*/
public class PageBean<T>{
private int currentPage= 1;//当前页,默认显示第一页
private int pageCount= 4;//每页显示的行数(查询返回的行数),默认每页显示4行
private int totalCount;//总记录数
private int totalPage;//总页数 =总记录数 / 每页显示的行数 (+ 1)
private List<T> pageData;//分页查询到的数据
//返回总页数
public int getTotalPage() {
if(totalCount% pageCount == 0) {
totalPage= totalCount/ pageCount;
}else{
totalPage= totalCount/ pageCount + 1;
}
return totalPage;
}
//get,set,构造函数略
}
- domain类
/**
* 1.实体类设计 (因为用了DbUtils组件,属性要与数据库中字段一致)
*/
public class Employee{
private int empId;//员工id
private String empName;//员工名称
private int dept_id;//部门id
//get,set略
}
- dao
//2.数据访问层,接口设计
public interface IEmployeeDao{
/**
*分页查询数据
*/
public void getAll(PageBean<Employee> pb);
/**
*查询总记录数
*/
public int getTotalCount();
}
- dao实现类
/**
* 2.数据访问层实现
*/
public class EmployeeDaoimplements IEmployeeDao{
@Override
public void getAll(PageBean<Employee> pb) {
//2.查询总记录数;设置到pb对象中
int totalCount=this.getTotalCount();
pb.setTotalCount(totalCount);
/*
*问题: jsp页面,如果当前页为首页,再点击上一页报错!
*如果当前页为末页,再点下一页显示有问题!
*解决:
* 1.如果当前页 <= 0;当前页设置当前页为1;
* 2.如果当前页 >最大页数;当前页设置为最大页数
*/
//判断
if(pb.getCurrentPage()<=0) {
pb.setCurrentPage(1);//把当前页设置为1
}else if(pb.getCurrentPage()> pb.getTotalPage()){
pb.setCurrentPage(pb.getTotalPage());//把当前页设置为最大页数
}
//1.获取当前页: 计算查询的起始行、返回的行数
int currentPage= pb.getCurrentPage();
int index=(currentPage-1)* pb.getPageCount();//查询的起始行
int count= pb.getPageCount();//查询返回的行数
//3.分页查询数据;把查询到的数据设置到pb对象中
String sql="select * from employee limit ?,?";
try{
//得到Queryrunner对象
QueryRunner qr= JdbcUtils.getQueryRuner();
//根据当前页,查询当前页数据(一页数据)
List<Employee> pageData= qr.query(sql,new BeanListHandler<Employee>(Employee.class), index, count);
//设置到pb对象中
pb.setPageData(pageData);
}catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public int getTotalCount() {
String sql="select count(*) from employee";
try{
//创建QueryRunner对象
QueryRunner qr= JdbcUtils.getQueryRuner();
//执行查询, 返回结果的第一行的第一列
Long count= qr.query(sql,new ScalarHandler<Long>());
return count.intValue();
}catch(Exception e) {
throw new RuntimeException(e);
}
}
}
- service接口层
//3.业务逻辑层接口设计
public interface IEmployeeService{
/**
*分页查询数据
*/
public void getAll(PageBean<Employee> pb);
}
- service实现层
//3.业务逻辑层,实现
public classEmployeeServiceimplementsIEmployeeService {
//创建Dao实例
privateIEmployeeDaoemployeeDao= new EmployeeDao();
@Override
public voidgetAll(PageBean<Employee>pb) {
try{
employeeDao.getAll(pb);
}catch(Exceptione) {
throw newRuntimeException(e);
}
}
}
- Servlet
/**
* 4.控制层开发
*/
public class IndexServletextends HttpServlet{
//创建Service实例
private IEmployeeService employeeService=new EmployeeService();
//跳转资源
private String uri;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
try{
//1.获取"当前页"参数; (第一次访问当前页为null)
String currPage= request.getParameter("currentPage");
//判断
if(currPage==null ||"".equals(currPage.trim())){
currPage="1";//第一次访问,设置当前页为1;
}
//转换
int currentPage= Integer.parseInt(currPage);
//2.创建PageBean对象,设置当前页参数; 传入service方法参数
PageBean<Employee> pageBean=new PageBean<Employee>();
pageBean.setCurrentPage(currentPage);
//3.调用service
employeeService.getAll(pageBean);//【pageBean已经被dao填充了数据】
//4.保存pageBean对象,到request域中
request.setAttribute("pageBean", pageBean);
//5.跳转
uri="/WEB-INF/list.jsp";
}catch(Exception e) {
e.printStackTrace();//测试使用
//出现错误,跳转到错误页面;给用户友好提示
uri="/error/error.jsp";
}
request.getRequestDispatcher(uri).forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
this.doGet(request, response);
}
}
- JSP
<html>
<head>
<title>分页查询数据</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
</head>
<body>
<tableborder="1"width="80%"align="center"cellpadding="5"cellspacing="0">
<tr>
<td>序号</td>
<td>员工编号</td>
<td>员工姓名</td>
</tr>
<!--迭代数据 -->
<c:choose>
<c:whentest="${not emptyrequestScope.pageBean.pageData}">
<c:forEachvar="emp"items="${requestScope.pageBean.pageData}"varStatus="vs">
<tr>
<td>${vs.count }</td>
<td>${emp.empId }</td>
<td>${emp.empName }</td>
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr>
<tdcolspan="3">对不起,没有你要找的数据</td>
</tr>
</c:otherwise>
</c:choose>
<tr>
<tdcolspan="3"align="center">
当前${requestScope.pageBean.currentPage }/${requestScope.pageBean.totalPage }页
<ahref="${pageContext.request.contextPath }/index?currentPage=1">首页</a>
<ahref="${pageContext.request.contextPath }/index?currentPage=${requestScope.pageBean.currentPage-1}">上一页</a>
<ahref="${pageContext.request.contextPath }/index?currentPage=${requestScope.pageBean.currentPage+1}">下一页</a>
<ahref="${pageContext.request.contextPath }/index?currentPage=${requestScope.pageBean.totalPage}">末页</a>
</td>
</tr>
</table>
</body>
</html>
- web.xml
<servlet>
<servlet-name>IndexServlet</servlet-name>
<servlet-class>cn.itcast.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>IndexServlet</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
- JavaEE的分页方法
- JavaEE-- 分页
- JavaEE中分页的具体实现
- javaEE 分页选择
- javaEE 初步实现分页
- javaee之分页练习
- JavaEE之分页
- JavaEE分页查询
- JavaEE中response.setContentType方法的使用
- javaee之servlet的方法详解
- JavaEE struts2.5的动态方法调用
- 【JavaEE】Servlet的doGet()和doPost()方法
- javaee 分页查询 排序 写法
- 较好的分页方法
- 通用的分页方法
- DataList的分页方法
- datalist分页的方法
- 分页的标准方法
- 【京东商城首页实战7】制作购物车
- iOS 指纹识别常见问题汇总
- java获取项目绝对路径
- php下载图片打开失败!
- 工作日记(中兴软创 四)
- JavaEE的分页方法
- 综合应用题:多线程复制文件(知识点:多线程、随机读写流)
- "gb2312", "utf-8”的区别
- CPP_Basic_Code_P9.1-PP9.6.4
- 关于Echarts的学习使用方法的建议
- hdu-2639-Bone Collector II【第K大背包】
- oracle中用户删除不了,ORA-01940提示 “无法删除当前已连接用户”
- Hadoop教程(三):HDFS、MapReduce、程序入门实践
- 【完全版】线段树