其实分页这一篇本来我是我不想写的,但是下来打算将泛型,为了泛型能够更加的容易理解,所以分页拖到了现在才写。
分页的实现有两种方式:
1.后台获取所有数据,然后通过前端框架来分页(不推荐,效率低,浪费资源);
2.通过后台数据库sql语句分页获取数据(在mysql和oracle中,分页的实现语句是不一样的,mysql通过limit关键字来实现分页,而oracle通过条件语句来实现;
在这里我们使用更加方便的limit来实现分页。下面我们使用一个案例来实现分页:
创建一个web项目,遍历user数据表的所有信息,以表格的形式展示,具体操作如下,工具类就不在这里写了。同时为了方便接口这里也不在创建了,直接写dao,service的实现
package com.zs.entity; public class User { private int uid; private String username; private String password; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } 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; } }
package com.zs.dao; import com.zs.util.DBUtils; import java.util.List; import java.util.Map; public class UserDao { /** * 获取所有的用户信息 * @return */ public List<Map<String,Object>> allUser() { String sql = "select * from user "; return DBUtils.executeQuery(sql); } }
package com.zs.service; import com.zs.dao.UserDao; import com.zs.entity.User; import java.util.ArrayList; import java.util.List; import java.util.Map; public class UserService { public List<User> allUser() { UserDao userDao = new UserDao(); List<Map<String, Object>> maps = userDao.allUser(); List<User> list = fengzhuang(maps); return list; } private List<User> fengzhuang(List<Map<String,Object>> maps) { List<User> list= new ArrayList<>(); for (Map<String, Object> map : maps) { User user = new User(); user.setUid((Integer) map.get("uid")); user.setUsername(map.get("username").toString()); user.setPassword(map.get("password").toString()); list.add(user); } return list; } }
package com.zs.servlet; import com.zs.entity.User; import com.zs.service.UserService; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @WebServlet("/home") public class UserServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { UserService userService = new UserService(); List<User> users = userService.allUser(); req.setAttribute("user", users); req.getRequestDispatcher("index.jsp").forward(req, resp); } }
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/7/3 Time: 14:18 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>$Title$</title> </head> <body> <table border="1" cellpadding="1"> <tr> <th>序号</th> <th>用户名</th> <th>密码</th> </tr> <c:forEach var="p" items="${user}" varStatus="i"> <tr> <td>${i.count}</td> <td>${p.username}</td> <td>${p.password}</td> </tr> </c:forEach> </table> </body> </html>
运行测试,可以看到表中数据以表格形式展示
但是这中方式,是一次性将所有的信息都读出来,如果信息量大的话,效率低而且展示数据表格会非常长,这很不方便阅读,因此就想,如何实现分页,将所有的数据分成一页一页 的,mysql使用limit关键字来实现分页,如下:
/** * startNum 开始下标, * num 每页的记录数 */ select * from user limit startNum,num;
通过limit实现分页,当点击下一页时,就根据发送过来的页数信息查询下一页的数据,然后在响应给前端页面,为了实现这种方式,我们创建一个分页的工具类,通过工具类来计算页数以及传递数据,工具类如下:
package com.zs.util; import com.zs.entity.User; import java.util.List; public class PageUtil { private int firstPage; private int proPage; private int currentPage; private int nextPage; private int lastPage; private List<User> list; public PageUtil() { } /** * 创建构造方法,通过传入当前页的值以及数据总数,计算下一页,上一页,首页,尾页以及当前页的数据等信息 * @param currentPage 当前页数 * @param countPage 总页数 * @param list 数据集合 */ public PageUtil(int currentPage,int countPage, List<User> list) { this.firstPage = 1; this.currentPage = currentPage; this.lastPage = countPage; this.proPage = this.currentPage == 1 ? 1 : (this.currentPage - 1); this.nextPage = this.currentPage == this.lastPage ? this.currentPage : this.currentPage + 1; this.list = list; } public int getFirstPage() { return firstPage; } public void setFirstPage(int firstPage) { this.firstPage = firstPage; } public int getProPage() { return proPage; } public void setProPage(int proPage) { this.proPage = proPage; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getNextPage() { return nextPage; } public void setNextPage(int nextPage) { this.nextPage = nextPage; } public int getLastPage() { return lastPage; } public void setLastPage(int lastPage) { this.lastPage = lastPage; } public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } }
然后修改dao层,service层,servlet以及页面如下:
package com.zs.dao; import com.zs.util.DBUtils; import java.util.List; import java.util.Map; public class UserDao { /** * 获取所有的用户信息 * @return */ public List<Map<String,Object>> allUser(int startNum) { String sql = "select * from user limit ?,3 "; return DBUtils.executeQuery(sql,startNum); } /** * 获取数据的记录数,方便计算总页数 * @return */ public Map<String,Object> countUser() { String sql = "select count(uid) as num from user"; return DBUtils.executeQuery(sql).get(0); } }
package com.zs.service; import com.zs.dao.UserDao; import com.zs.entity.User; import com.zs.util.PageUtil; import java.util.ArrayList; import java.util.List; import java.util.Map; public class UserService { public PageUtil allUser(int currentPage) { UserDao userDao = new UserDao(); Map<String, Object> map = userDao.countUser(); /*获取总记录数*/ int num =Integer.parseInt(map.get("num").toString()) ; /*获取当前页数据, (currentPage-1)*10计算开始下标*/ List<Map<String, Object>> maps = userDao.allUser((currentPage-1)*3); List<User> list = fengzhuang(maps); PageUtil page = new PageUtil(currentPage, (num+2)/3, list); return page; } private List<User> fengzhuang(List<Map<String,Object>> maps) { List<User> list= new ArrayList<>(); for (Map<String, Object> map : maps) { User user = new User(); user.setUid((Integer) map.get("uid")); user.setUsername(map.get("username").toString()); user.setPassword(map.get("password").toString()); list.add(user); } return list; } }
package com.zs.servlet; import com.zs.entity.User; import com.zs.service.UserService; import com.zs.util.PageUtil; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @WebServlet("/home") public class UserServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Integer currentPage = 1; try { currentPage = Integer.parseInt(req.getParameter("page")); } catch (Exception e) { System.out.println("第一次访问"); } UserService userService = new UserService(); PageUtil page = userService.allUser(currentPage); req.setAttribute("page", page); req.getRequestDispatcher("index.jsp").forward(req, resp); } }
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/7/3 Time: 14:18 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>$Title$</title> </head> <body> <table border="1" cellpadding="1"> <tr> <th>序号</th> <th>用户名</th> <th>密码</th> </tr> <c:forEach var="p" items="${page.list}" varStatus="i"> <tr> <td>${i.count}</td> <td>${p.username}</td> <td>${p.password}</td> </tr> </c:forEach> </table> <%--分页工具--%> <div> <a href="<c:url value='/home?page=${page.firstPage}'/>">首页</a> <a href="<c:url value='/home?page=${page.proPage}'/>">上一页</a> 第${page.currentPage}/${page.lastPage}页 <a href="<c:url value='/home?page=${page.nextPage}'/>">下一页</a> <a href="<c:url value='/home?page=${page.lastPage}'/>">尾页</a> </div> </body> </html>
然后运行测试: