分页技术实现分析
分页技术:
JSP页面,用来显示数据! 如果数据有1000条,分页显示,每页显示10条,共100页; 好处: 利于页面布局,且显示的效率高!
分页关键点:
- 分页SQL语句;
- 后台处理: dao/service/servlet/JSP
实现步骤:
- 环境准备
a) 引入jar文件及引入配置文件
i. 数据库驱动包
ii. C3P0连接池jar文件 及 配置文件
iii. DbUtis组件: QueryRunner qr = new QueryRuner(dataSouce); qr.update(sql);
b)公用类: JdbcUtils.java
- 先设计:PageBean.java
- Dao接口设计/实现: 2个方法
- Service/servlet
- JSP
示例核心代码:
package com.loaderman.demo.entity; /** * 1. 实体类设计 (因为用了DbUtils组件,属性要与数据库中字段一致) * */ public class Employee { private int empId; // 员工id private String empName; // 员工名称 private int dept_id; // 部门id public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public int getDept_id() { return dept_id; } public void setDept_id(int deptId) { dept_id = deptId; } }
package com.loaderman.demo.dao.impl; import java.util.List; import com.loaderman.demo.dao.IEmployeeDao; import com.loaderman.demo.entity.Employee; import com.loaderman.demo.utils.JdbcUtils; import com.loaderman.demo.utils.PageBean; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; /** * 2. 数据访问层实现 * @author Jie.Yuan * */ public class EmployeeDao implements 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); } } }
package com.loaderman.demo.service.impl; import com.loaderman.demo.dao.IEmployeeDao; import com.loaderman.demo.dao.impl.EmployeeDao; import com.loaderman.demo.entity.Employee; import com.loaderman.demo.service.IEmployeeService; import com.loaderman.demo.utils.PageBean; /** * 3. 业务逻辑层,实现 * @author Jie.Yuan * */ public class EmployeeService implements IEmployeeService { // 创建Dao实例 private IEmployeeDao employeeDao = new EmployeeDao(); @Override public void getAll(PageBean<Employee> pb) { try { employeeDao.getAll(pb); } catch (Exception e) { throw new RuntimeException(e); } } }
package com.loaderman.demo.servlet; import com.loaderman.demo.entity.Employee; import com.loaderman.demo.service.IEmployeeService; import com.loaderman.demo.service.impl.EmployeeService; import com.loaderman.demo.utils.PageBean; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 4. 控制层开发 * @author Jie.Yuan * */ public class IndexServlet extends 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); } }
package com.loaderman.demo.utils; import java.util.List; /** * 封装分页的参数 * * @author Jie.Yuan * */ 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; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getPageCount() { return pageCount; } public void setPageCount(int pageCount) { this.pageCount = pageCount; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public List<T> getPageData() { return pageData; } public void setPageData(List<T> pageData) { this.pageData = pageData; } }
最后,关注【码上加油站】微信公众号后,有疑惑有问题想加油的小伙伴可以码上加入社群,让我们一起码上加油吧!!!