- 物理分页
只从数据库中查询出要显示的数据
优点:不占用很多内存
缺点:速度比较低,每一次都要从数据库中获取
- 逻辑分页
从数据库中将所有记录查找到,存储到内存中,需要什么数据
直接从内存中获取.
优点:速度比较快
缺点:占用比较多的内存,如果数据比较多,可以出现内在溢出。
数据实时更新需要单独处理.
mysql中limit介绍
利用mysql的limit,进行物理分页。
select * from 表名 limit m,n;
m是从0开始,代表是第几条记录
n代表显示多少条记录
例如
select * from person limit 4,10;
从第五条记录开始,显示10条.
分页实现原理分析
1.知道一共有多少条记录
select count(*) from 表;
2.知道每一页显示多少条记录
人为定义的.
3.一共有多少页
1.总页数=总条数%每页条数==0?总条数/每页条数:总条数/每页条数+1
2.总页数=Math.ceil(总条数*1.0/每页条数);
4.当前页码
默认值为1,代表第一页.
当点击上一页,下一页,就是对页码进行+1 -1操作.
5.需要当前页的数据
例如:每页显示五条,要查询第三页数据
select * from 表 limit(3-1)*5,5;
用(当前页码-1)*每页条数,就求出了开始的记录位置,在向下查找每页数个记录。就得到了这页的数据
注意:limit是mysql数据库特有的,它可以相当于是mysql的方言。
Sqlserver top
Oracle rownum
------------------------------
扩展:我们可以通过jdbc写出脱离数据库的分页操作。
- 将结果集设置成滚动结果集。
可以使用它的absolute方法将游标定位到指定位置。
.
分页原理:
- 数据一共有几条
SELECT COUNT(*) FROM products; 一共11条 totalCount
- 每页显示几条数据
人为定义的,假设我们规定一页显示4条数据。 currentCount
- 求出一共有多少页 totalpage
totalpage=Math.ceil(1.0*totalCount/currentCount); //java中两个整数int运算结果还是个整数,所以乘以1.0,就不是整数运算啦,向上取整以后是3
totalpage=totalCount%currentCount==0?: totalCount/currentCount; totalCount/currentCount+1 //除尽等于零
- 求出当前页 currentPage
默认是第一页 上一页就是在当前页基础上-1 下一页就是在当前页基础上+1
如果是第一页,一定没有上一页,如果是最后一页,一定没有下一页。
- 求出当前页的数据
Select * from product limit (当前页-1)*每页条数,每页条数;
首先我们需要做个分页javabean
import java.util.List; public class PageBean { private int totalCount; // 总条数 private int totalPage; // 总页数 private int currentPage; // 当前页 private int currentCount; // 每页条数 private List<Product> ps; // 当前页数据. public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getTotalPage() { 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 getCurrentCount() { return currentCount; } public void setCurrentCount(int currentCount) { this.currentCount = currentCount; } public List<Product> getPs() { return ps; } public void setPs(List<Product> ps) { this.ps = ps; } }
使用这个PageBean的目的是为了将分页的相关数据携带到页面上。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> </head>
<body> <div id="divpagecontent"> <table width="100%" border="0" cellspacing="0"> <tr> <td> <div style="text-align:right; margin:5px 10px 5px 0px"> <a href="index.jsp">首页</a> 计算机 图书列表 </div> <table cellspacing="0" class="listcontent"> <tr> <td> <h1>商品目录</h1> <hr /> <h1>计算机</h1> 共100种商品 <hr /> <div style="margin-top:20px; margin-bottom:5px"> <img src="images/productlist.gif" width="100%" height="38" /> </div> <table cellspacing="0" class="booklist"> <tr> <c:forEach items="${bean.ps}" var="p"> <td> <div class="divbookpic"> <p> <a href="#"><img src="" width="115" height="129" border="0" /></a> </p> </div> <div class="divlisttitle"> <a href="#">书名:${p.name}<br />售价:${p.price} </a> </div></td> </c:forEach> </tr> </table> <div class="pagination"> <ul> <c:if test="${bean.currentPage==1}"> <li class="disablepage"><<上一页</li> </c:if> <c:if test="${bean.currentPage!=1}"> <li><a href="${pageContext.request.contextPath}/listProductByPage?currentPage=${bean.currentPage-1}"> <<上一页</a> </li> </c:if> <li class="currentpage">1</li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <c:if test="${bean.currentPage==bean.totalPage}"> <li class="disablepage">下一页>></li> </c:if> <c:if test="${bean.currentPage!=bean.totalPage}"> <li class="nextPage"> <a href="${pageContext.request.contextPath}/listProductByPage?currentPage=${bean.currentPage+1}"> 下一页>></a> </li> </c:if> </ul> </div></td> </tr> </table> </td> </tr> </table> </div> </body> </html>
public class ListProductByPageServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.定义出每页条数 int currentCount = 4;// 默认每页显示4条件 // 2.定义出当前页码 int currentPage = 1;// 默认是第一页 String _currentPage = request.getParameter("currentPage"); if (_currentPage != null) { currentPage = Integer.parseInt(_currentPage); // 如果当前_currentPage不为null说明浏览器端传递过来了页码,我们就让当前的页码不在为1,而是传递过来的值 } // 3.调用service中分页查询的方法。 ProductService service = new ProductService(); try { PageBean bean = service.findByPage(currentCount, currentPage); request.setAttribute("bean", bean); request.getRequestDispatcher("/product_list.jsp").forward(request, response); } catch (SQLException e) { e.printStackTrace(); } } }
public class ProductService { ProductDao dao = new ProductDao(); // 分页显示数据 // currentCount 每页条数 // currentPage 当前页 public PageBean findByPage(int currentCount, int currentPage) throws SQLException { // 1.求出总条数 int totalCount = dao.findAllCount(); // 2.求出总页数 int totalPage = (int) Math.ceil(1.0 * totalCount / currentCount); // 3.求出当前页的数据 List<Product> ps = dao.findByPage(currentCount, currentPage); PageBean bean = new PageBean(); bean.setTotalCount(totalCount); bean.setTotalPage(totalPage); bean.setCurrentCount(currentCount); bean.setCurrentPage(currentPage); bean.setPs(ps); return bean; } }
public class ProductDao { // 求出数据总条数 public int findAllCount() throws SQLException { // 1.创建一个QueryRunner QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource()); // 2.执行sql Long count = (Long) runner.query("select count(*) from products", new ScalarHandler()); return count.intValue(); } // 查询出当前页的数据 // currentCount 每页条数 // currentPage 当前页 public List<Product> findByPage(int currentCount, int currentPage) throws SQLException { // 1.创建一个QueryRunner QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource()); // 2.执行sql return runner.query("select * from products limit ?,?", new BeanListHandler<Product>(Product.class), (currentPage - 1) * currentCount, currentCount); } }