Java+Jsp+Servlet+Tomcat 实现分页

本文深入探讨了Web应用中分页技术的实现方法,对比了内存分页与数据库分页的优劣,详细介绍了如何使用MySQL数据库进行高效分页查询,包括SQL语句的编写、分页逻辑的实现及代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

我们Web端经常要用到 分页 功能,便于用户更方便的查询和展示他所需要的数据。


为什么需要分页?
  1. 即能显示多条数据,又不需要拖动页面,是数据更加清晰直观,页面不再冗长,也不受数据量的限制。
大容量的数据显示的缺点:
  1. 当数据量较多时,用户需要拖动页面才能浏览更多信息。
  2. 数据定位不便。

现分页的方式下面两种:

  1. 将所有查询结果以集合等形式保存在内存中,翻页时从中取出一页所需的数据显示。

    这种方法有两个主要的缺点:

    1. 用户看到的可能是过期数据;
    2. 如果数据量非常大,查询一次数据集会耗费很长时间,并且存储的数据也会占用大量内存开销。
  2. 每次翻页时只从数据库中检索出本页需要的数据。(重点,主讲这种方法)

    1. 虽然每次翻页都查询数据库,但查询出的记录数相对较少,总体开销不大,再配以连接池技术以及其他查询优化。可以达到比高的效率。

分页的步骤

  1. 确定每页显示的数据
  2. 计算显示的总页数
  3. 编写Sql语句,实现数据的查询
  4. 在Jsp页面进行分页

分析以上分页的步骤

  1. 根据实际的页面设计,确定在数据列表中每次显示多少条记录 . 即每次从数据库中需要查询多少条记录用于页面显示,通常这个数量可以在开发时定义好,也可以由用户来选择;

  2. 既然要进行分页显示,还需清楚按照每页显示的记录数量总共会产生多少页数据,在页面中示的记录数量是已知的,而数据库中符合展示条件的记录总数是未知的;

  3. 通过Mysql数据库查询,获取 得到总数据库数据的条数步骤:

    select count(1) from 表名 效率高于 select count(*) from 表名

  • 起始行偏移量=(当前页页码-1) *每页显示的记录数;

  • SELECT * FROM 表名 LIMIT (当前页页码-1) *每页显示的记录数,每页显示的记录数

  • 获取每页显示的的记录数(数据库查询的),传入参数总条数,和记录总页数

  • 有了需要展示的记录总数后,就可以根据 每页显示的记录数 计算共需要划分为多少页。基于方便代码管理的考虑,将有关分页的数据封装到一个Page 类中 ,其中包括每页显示的数据量、数据的总数量、显示的总页数、当前页码、每页显示的数据集合。

  1. 定义一个 Page类 里面存放一些关于分页的变量,如,分页总页数,当前页数,
    数据库数据的总条数 等等…
  • 数据库里的总条数

  • 分页时的总页数,按照数据库里的数据,分总共分多少页

  • 当前页码

  • 分页后每页显示的条数

  • 分页后每页显示的数据,定义List集合

在Page类中直接判断 计算分页的总页数

分页的总页数=(总页数% 每页显示的条数==0)?(总页数/每页显示的条数):((总页数/每页显示的条数)+1);


实例详细讲解

Mysql数据库:Page表

CREATE DATABASE Paging

DROP TABLE page
CREATE TABLE page(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(40) NOT NULL,
	age INT NOT NULL,
	pclass VARCHAR(40) NOT NULL,
	sex VARCHAR(2) NOT NULL
	
)

SELECT * FROM page LIMIT 3,3
SELECT COUNT(1) FROM page

INSERT INTO page VALUES(DEFAULT,'张三',20,'s122','男');
INSERT INTO page VALUES(DEFAULT,'李四',21,'s222','女');
INSERT INTO page VALUES(DEFAULT,'王五',19,'s122','男');
INSERT INTO page VALUES(DEFAULT,'大大',24,'s122','男');
INSERT INTO page VALUES(DEFAULT,'小小',26,'s222','女');
INSERT INTO page VALUES(DEFAULT,'大小',28,'s122','男');
INSERT INTO page VALUES(DEFAULT,'小大',22,'s122','女');
INSERT INTO page VALUES(DEFAULT,'哈哈',21,'s222','女');

封装实体类

package com.bdqn.Entity;

public class PageEntity {
	private int id;
	private String name;
	private int age;
	private String pclass;
	private String sex;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getPclass() {
		return pclass;
	}
	public void setPclass(String pclass) {
		this.pclass = pclass;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public PageEntity(int id, String name, int age, String pclass, String sex) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.pclass = pclass;
		this.sex = sex;
	}
	public PageEntity() {
		super();
	}
	
}


封装Page类

package com.bdqn.Entity;

import java.util.List;

public class Page {
	//数据库里的总条数
	private int pageSum;
	//分页时的总页数,按照数据库里的数据,分总共分多少页
	private int pageSize;
	//当前页码
	private int dangPage;
	//分页后每页显示的条数
	private int pageTiao=3;	
	//分页后每页显示的数据
	private List<PageEntity> getPageList;
	
	public int getPageSum() {
		return pageSum;
	}
	public void setPageSum(int pageSum) {
		this.pageSum = pageSum;
	}
	//这个方法只设定get()方法即可
	public int getPageSize() {
		return this.pageSize=(pageSum % pageTiao==0)?(pageSum/pageSize):((pageSum/pageTiao)+1);
	}
	public int getDangPage() {
		return dangPage;
	}
	public void setDangPage(int dangPage) {
		this.dangPage = dangPage;
	}
	public int getPageTiao() {
		return pageTiao;
	}
	public List<PageEntity> getGetPageList() {
		return getPageList;
	}
	public void setGetPageList(List<PageEntity> getPageList) {
		this.getPageList = getPageList;
	}
	
	
}

封装BaseDao类

package com.bdqn.Dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class BaseDao {
		//加载文件中的配置信息
		protected Connection conn;
		private static String driver; // 数据库驱动字符串
		private static String url; // 连接URL字符串
		private static String user; // 数据库用户名
		private static String password; // 用户密码
		static{
			init();
		}
		public static void init(){
			Properties params=new Properties();
			String file ="database.properties";
			InputStream is=BaseDao.class.getClassLoader().getResourceAsStream(file);
			try {
				params.load(is);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			driver=params.getProperty("driver");
			url=params.getProperty("url");
			user=params.getProperty("user");
			password=params.getProperty("password");
			
		}
		
		
		public Connection getConnection(){
				try {
					//加载驱动
					Class.forName(driver);
				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					//连接
					conn=DriverManager.getConnection(url,user,password);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			return conn;
		}
			
			//关闭
			public void closeAll(Connection conn, Statement stmt, ResultSet rs) {
				// 若结果集对象不为空,则关闭
				if (rs != null) {
					try {
						rs.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
				} 
				// 若Statement对象不为空,则关闭
				if (stmt != null) {
					try {
						stmt.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				// 若数据库连接对象不为空,则关闭
				if (conn != null) {
					try {
						conn.close();
					} catch (Exception e) { 
						e.printStackTrace();
					}
				}
			}
		
}

BaseDao配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名?useUnicode&characterEncoding=utf8
user=数据库用户名
password=数据库密码

封装Dao层

接口

package com.bdqn.Dao;

import java.util.List;

import com.bdqn.Entity.PageEntity;

public interface PageDao {
	//获取数据库总条数
	public int SumSize();
	//获取每次分页要显示的数据,
	public List<PageEntity> getPageList(int dangpage,int pageize);
}

实现类

package com.bdqn.Dao.Impl;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.bdqn.Dao.BaseDao;
import com.bdqn.Dao.PageDao;
import com.bdqn.Entity.PageEntity;

public class PageDaoImpl extends BaseDao implements PageDao{

	/**
	 * 查询总页数
	 */
	@Override
	public int SumSize() {
		conn=this.getConnection();
		PreparedStatement ps=null;
		ResultSet rs=null;
		int count=0;
		try {
			//获取总记录数
			String sql="SELECT COUNT(1) FROM page";			
			ps=conn.prepareStatement(sql);
			rs=ps.executeQuery();
			while (rs.next()) {
				count=rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			closeAll(getConnection(), ps, null);
		}
		return count;
	}

	/**
	 * 按分页查询的数据
	 */
	@Override
	public List<PageEntity> getPageList(int dangpage,int pagesize) {
		conn=this.getConnection();
		PreparedStatement ps=null;
		ResultSet rs=null;
		List<PageEntity> page=new ArrayList<PageEntity>();
		try {
			String sql="SELECT * FROM page LIMIT ?,?";
			ps=conn.prepareStatement(sql);
			ps.setInt(1, (dangpage-1)*pagesize);
			ps.setInt(2, pagesize);
			rs=ps.executeQuery();
			while (rs.next()) {
				PageEntity stu=new PageEntity(rs.getInt("id"),rs.getString("name"),rs.getInt("age"),rs.getString("pclass"),rs.getString("sex"));
				page.add(stu);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			closeAll(getConnection(), ps, rs);
		}
		return page;
	}

}

封装Biz层

接口

package com.bdqn.Biz;

import com.bdqn.Entity.Page;

public interface PageBiz {
	//在biz把前面封住的类联合,传入参数当前页码
	public Page getPage(int dangpage);
}

实现类

package com.bdqn.Biz.Impl;

import java.util.List;

import com.bdqn.Biz.PageBiz;
import com.bdqn.Dao.BaseDao;
import com.bdqn.Dao.PageDao;
import com.bdqn.Dao.Impl.PageDaoImpl;
import com.bdqn.Entity.Page;
import com.bdqn.Entity.PageEntity;

public class PageBizImpl extends BaseDao implements PageBiz {

	@Override
	public Page getPage(int dangpage) {
		PageDao pd=new PageDaoImpl();
		Page p=new Page();
		p.setPageSum(pd.SumSize());
		p.setDangPage(dangpage);
		List<PageEntity> pagelist=pd.getPageList(dangpage, p.getPageSize());
		p.setGetPageList(pagelist);
		return p;
	}

}

Servlet类的doPost方法

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		//取得jsp页码传进来的当前页码
		Integer d=1;
		String dang=request.getParameter("dangPage");
		if (dang!=null) {
			d=Integer.parseInt(dang);
		}
		PageBiz pb=new PageBizImpl();
		Page page=pb.getPage(d);
		request.setAttribute("page", page);
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}

配置Servlet类Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <servlet-name>PageServlet</servlet-name>
    <servlet-class>com.bdqn.Servlet.PageServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>PageServlet</servlet-name>
    <url-pattern>/PageServlet</url-pattern>
  </servlet-mapping>

</web-app>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
  		<c:if test="${page==null }">
  			<%response.sendRedirect("PageServlet"); %>
  		</c:if>
  		
    	<table border="1px solid bluck">
    		<caption>学生信息实现分页</caption>
  			<tr><td>学生编号</td><td>学生姓名</td><td>学生年龄</td><td>学生班级</td><td>学生性别</td></tr>
  				<c:forEach var="p" items="${page.getPageList }">
  					<tr>
  						<td>${p.id }</td>
  						<td>${p.name }</td>
  						<td>${p.age }</td>
  						<td>${p.pclass }</td>
  						<td>${p.sex }</td>
  					</tr>
  				</c:forEach>
  				<tr>
  					<td colspan="5">
  						现在是${page.dangPage}/${page.pageSize}页
  						<a href="PageServlet?dangPage=1">首页</a>
	  						<c:if test="${page.dangPage>1}">
	    						<a href="PageServlet?dangPage=${page.dangPage-1}">上一页</a>
			    			</c:if>
			    			<c:if test="${page.dangPage < page.pageSize}">
			    				<a href="PageServlet?dangPage=${page.dangPage+1}">下一页</a>
			    			</c:if>
  						<a href="PageServlet?dangPage=${page.pageSize }">末页</a>
  					</td>
  				</tr>
    	</table>
  </body>
</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值