前言
我们Web端经常要用到 分页 功能,便于用户更方便的查询和展示他所需要的数据。
为什么需要分页?
- 即能显示多条数据,又不需要拖动页面,是数据更加清晰直观,页面不再冗长,也不受数据量的限制。
大容量的数据显示的缺点:
- 当数据量较多时,用户需要拖动页面才能浏览更多信息。
- 数据定位不便。
现分页的方式下面两种:
-
将所有查询结果以集合等形式保存在内存中,翻页时从中取出一页所需的数据显示。
这种方法有两个主要的缺点:
- 用户看到的可能是过期数据;
- 如果数据量非常大,查询一次数据集会耗费很长时间,并且存储的数据也会占用大量内存开销。
-
每次翻页时只从数据库中检索出本页需要的数据。(重点,主讲这种方法)
- 虽然每次翻页都查询数据库,但查询出的记录数相对较少,总体开销不大,再配以连接池技术以及其他查询优化。可以达到比高的效率。
分页的步骤
- 确定每页显示的数据
- 计算显示的总页数
- 编写Sql语句,实现数据的查询
- 在Jsp页面进行分页
分析以上分页的步骤
-
根据实际的页面设计,确定在数据列表中每次显示多少条记录 . 即每次从数据库中需要查询多少条记录用于页面显示,通常这个数量可以在开发时定义好,也可以由用户来选择;
-
既然要进行分页显示,还需清楚按照每页显示的记录数量总共会产生多少页数据,在页面中示的记录数量是已知的,而数据库中符合展示条件的记录总数是未知的;
-
通过Mysql数据库查询,获取 得到总数据库数据的条数步骤:
select count(1) from 表名 效率高于 select count(*) from 表名
-
起始行偏移量=(当前页页码-1) *每页显示的记录数;
-
SELECT * FROM 表名 LIMIT
(当前页页码-1) *每页显示的记录数,每页显示的记录数 -
获取每页显示的的记录数(数据库查询的),传入参数总条数,和记录总页数
-
有了需要展示的记录总数后,就可以根据 每页显示的记录数 计算共需要划分为多少页。基于方便代码管理的考虑,将有关分页的数据封装到一个Page 类中 ,其中包括每页显示的数据量、数据的总数量、显示的总页数、当前页码、每页显示的数据集合。
- 定义一个 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>