web_day43_分页查询

一、分页简介

1、概念

查询时的数据的分割:数据的分页

2、种类

物理分页:(最常用)

数据库层次上的分页:查询数据时分页

优点:

  1. 占用web服务器(tomcat)内存资源极少(几乎可以忽略)

缺点:

  1. 增加了服务器和数据库的通信次数,增加了数据库的查询压力

表中的数据量极大的情况下,最好用物理分页

逻辑分页:

把数据一次性查询到服务器内存中,在显示的时候写算法进行分页

优点:

  1. 只查询一次,大大减少了服务器和数据库的通信次数

缺点:

  1. java集合无法一次性保存过多的数据
  2. 太占用web服务器的内存资源

表中的数据量没有到达万的级别,可以选择用逻辑分页 减少数据库的查询压力

区别:

物理分页:

通过SQL语句直接操作数据库,占用WEB服务器的内存很少,但是对数据库的查询压力比较大

逻辑分页:

一次将所有的数据查询出来放到WEB服务器的内存中去,通过算法计算分页的相关的数据出来,对数据库的查询压力很低,但是对WEB服务器的内存占用极大

二、物理分页

select * from product  limit 6;--查询前6条数据

select * from product  limit 0,6;--起始记录行号,一次查询几条记录

select * from product limit ?,?

第一个参数:查询的起始索引下标,计算公式为 (要查询第几页-1)*每页显示的记录数

第二个参数:每页显示的记录数

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>Insert title here</title>
	<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/imagetable.css">
	<style type="text/css">
		a{
			text-decoration: none;
			color:gray;
		}
	</style>
</head>
<body>
	<table border="1" width="40%" class="imagetable" align="center">
		<tr>
			<th>商品列表</th>
		</tr>
	</table>
	<hr/>
	<table border="1" width="100%" class="imagetable">
		<tr>
			<th colspan="5" align="right">
				<input type="button" value="添加商品"/>
			</th>
		</tr>
		<tr>
			<th style="width: 110px">商品序号</th>
			<th>商品名称</th>
			<th style="width: 110px">商品图片</th>
			<th style="width: 110px">商品价格</th>
			<th>商品描述</th>
		</tr>
		<c:if test="${not empty pageBean && not empty pageBean.result }">
			<c:forEach items="${pageBean.result }" var="product" varStatus="vs">
				<tr>
					<td align="center">${vs.count }</td>
					<td>${product.pname }</td>
					<td align="center">
						<img src="${product.pimage }" width="45px" height="45px">
					</td>
					<td align="center">${product.shop_price }</td>
					<td>${product.pdesc }</td>
				</tr>
			</c:forEach>
		</c:if>
		<!-- 显示分页条 -->
		<tr>
			<td colspan="5" align="right">
				<!-- 上一页:当前页为第一页,上一页不可点 -->
				<c:if test="${not empty pageBean }">
					<c:choose>
						<c:when test="${pageBean.pageNumber==1 }">
							<a href="javascript:void(0);">上一页</a>
						</c:when>
						<c:otherwise>
							<a href="${pageContext.request.contextPath }/FindAllProductForPageServlet?pageNumber=${param.pageNumber-1}">上一页</a>
						</c:otherwise>
					</c:choose>
				</c:if>
				
				<!-- 当前页码:当前页不可点 -->
				<c:if test="${not empty pageBean }">
					<c:forEach begin="1" end="${pageBean.totalPage }" var="i">
						<c:choose>
							<c:when test="${pageBean.pageNumber==i }">
								<a href="javascript:void(0);">${i }</a>
							</c:when>
							<c:otherwise>
								<a href="${pageContext.request.contextPath }/FindAllProductForPageServlet?pageNumber=${i}">${i }</a>
							</c:otherwise>
						</c:choose>
					</c:forEach>
				</c:if>
				
				<!-- 下一页 :当前页为最后一页,下一页不可点-->
				<c:if test="${not empty pageBean }">
					<c:choose>
						<c:when test="${pageBean.pageNumber==pageBean.totalPage }">
							<a href="javascript:void(0);">下一页</a>
						</c:when>
						<c:otherwise>
							<a href="${pageContext.request.contextPath }/FindAllProductForPageServlet?pageNumber=${param.pageNumber+1}">下一页</a>
						</c:otherwise>
					</c:choose>
				</c:if>
			</td>
		</tr>
	</table>
</body>
</html>
package com.itheima.domain;

import java.io.Serializable;
import java.util.List;


public class PageBean<T> implements Serializable {
    
    // 分页查询的数据
    private List<T> result;
    
    // 总记录数(查询得到)
    private int totalRecord;
    
    // 每页显示大小(固定写死)
    private int pageSize;

    // 要查看页码(前台用户传递)
    private int pageNumber;

    // 起始索引(计算得来)
    private int startIndex;

    // 总页码数(计算得来 总记录数、每页显示大小)
    private int totalPage;

    public int getStartIndex() {
        return startIndex = (this.getPageNumber() - 1) * this.getPageSize();
    }

    // 计算起始索引在当前JavaBean,不在外部,所以可以不用写setter
    /*public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }*/

    //通过当前JavaBean的数据就可以完成计算
    public int getTotalPage() {
        return totalPage = this.getTotalRecord() % this.getPageSize() == 0
                ? this.getTotalRecord() / this.getPageSize()
                : (this.getTotalRecord() / this.getPageSize() + 1);
    }

    // 计算总页码数在当前JavaBean,不在外部,所以可以不用写setter
    /*public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }*/

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(int totalRecord) {
        this.totalRecord = totalRecord;
    }

    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public List<T> getResult() {
        return result;
    }

    public void setResult(List<T> result) {
        this.result = result;
    }

    public PageBean() {

    }
}
package com.itheima.web.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.itheima.domain.PageBean;
import com.itheima.domain.Product;
import com.itheima.service.ProductService;
import com.itheima.service.impl.ProductServiceImpl;

/**
 * 分页查询
 *
 */
public class FindAllProductForPageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public FindAllProductForPageServlet() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        //0.获取用户要查看的页码数
        int pageNumber = Integer.parseInt(request.getParameter("pageNumber"));
        
        //创建PageBean
        PageBean<Product> pageBean = new PageBean<Product>();
        pageBean.setPageNumber(pageNumber);
        
        // 1.直接调用service层查询所有商品信息的方法
        ProductService service = new ProductServiceImpl();
        try {
            pageBean = service.findAllProductForPage(pageBean);
            // 2.将查询的结果保存到域对象
            request.setAttribute("pageBean", pageBean);
            // 3.转发到显示所有商品信息的页面
            request.getRequestDispatcher("plist.jsp").forward(request, response);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
package com.itheima.service.impl;

import java.sql.Connection;
import java.util.List;

import com.itheima.dao.ProductDao;
import com.itheima.dao.impl.ProductDaoImpl;
import com.itheima.domain.PageBean;
import com.itheima.domain.Product;
import com.itheima.service.ProductService;
import com.itheima.utils.C3P0Utils;

public class ProductServiceImpl implements ProductService {

	private ProductDao dao = new ProductDaoImpl();

	@Override
	public PageBean<Product> findAllProductForPage(PageBean<Product> pageBean) throws Exception {
		/**
         * 业务代码书写的位置划分(目前有2种情况建议将业务代码写到JavaBean中)
         * 1.所有涉及计算的数据在JavaBean中都能直接拿到的
         * 2.没有提供setter方法,只能将业务代码写到JavaBean中
         * 
         */
        
        //每页显示大小pageSize(实际开发中写在配置文件中)
        int pageSize = 7;
        pageBean.setPageSize(pageSize);
        
        /*//起始索引 startIndex(计算得来) 起始索引=(要查看的页码数-1)*每页显示大小  【要查看的页码数一般是由用户指定!】
        int startIndex = (pageBean.getPageNumber()-1)*pageSize;*/
        
        //获得总记录数totalRecord(查询得到)
        int totalRecord = dao.getTotalRecord();
        pageBean.setTotalRecord(totalRecord);
        
        //总页码totalPage(计算得来)【问题:现在总页码计算结果在service层,无法显示在页面;一般显示都是在servlet中将数据保存到域对象,转发到页面获取】
        //如何处理呢?将这个数据封装到JavaBean,在service层计算后,将其对应的对象作为方法的返回值,问题又来了,分页查询的数据又不好使使了!!!!
        //干脆将分页查询的数据也搞到JavaBean!
        /*int totalPage = totalRecord%pageSize==0?totalRecord/pageSize:totalRecord/pageSize+1;
        pageBean.setTotalPage(totalPage);*/
        
        List<Product> products = dao.findAllProductForPage(pageBean.getStartIndex(),pageBean.getPageSize());
        pageBean.setResult(products);
        
        return pageBean;
	}

}
package com.itheima.dao.impl;

import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.itheima.dao.ProductDao;
import com.itheima.domain.Product;
import com.itheima.utils.C3P0Utils;

public class ProductDaoImpl implements ProductDao {

	@Override
	public int getTotalRecord() throws Exception {
		 // 1.获得QueryRunner核心对象
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.编写SQL语句
        String sql = "select count(*) from product where pflag=?";
        // 3.设置实际参数
        Object[] params = { 0 };
        // 4.执行查询操作
        Long count = (Long) qr.query(sql, new ScalarHandler(), params);
        return count.intValue();
	}

	@Override
	public List<Product> findAllProductForPage(int startIndex, int pageSize) throws Exception {
		 // 1.获得QueryRunner核心对象
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.编写SQL语句
        String sql = "select * from product where pflag=? limit ?,?";
        // 3.设置实际参数
        Object[] params = { 0, startIndex, pageSize };
        // 4.执行查询操作
        return qr.query(sql, new BeanListHandler<>(Product.class), params);
	}


}

http://localhost:8080/web_day43/FindAllProductForPageServlet?pageNumber=1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值