分页技术实现

基于WEB的分页技术实现

分页概述

​ 分页是一种常用的页面数据显示技术,分页能够通过减少页面数据处理量从而提高了系
统的性能。分页是综合技术的应用,涵盖了前端+Java后端+数据库等技术知识点;常用的
分页技术有以下两种︰

内存分页
第一次访问时,读取所有记录,放入session ( request、map、list也可以存放)对
象中,然后每次从session或 request内置对象中读取出当前页的数据。

数据库分页(重点掌握)
每次访问数据库,从数据库中取出当前页的数据。

内存分页与数据库分页区别
当数据量比较少时,第一种方法无疑是要快一些,因为减少与数据库的连接访问。而当
数据量比较大时,那么内存的开销是十分大的,放到 session或request 中还有一个问题是

不能及时的清除无用的对象,而且这么大数据量在网络中传输也会使系统变得很慢。第二种

方法就是专门解决这个问题的,它每次访问数据库,只读取当前页所需的记录,大大的减少网络

传输量,它不会把页数据放到session或 request中,大大提高服务器的性能。
在实际的开发中,我们通过对分页代码的封装,能够快速引用到我们项园由,减少
开发时间及避免代码重用,提高开发效率。

内存分页技术实现

1、创建数据表

创建数据表,表中字段如下:(注意user_id要设置成自动增长)

分页技术实现

操作新建的表page:

insert into page(user_name,user_age,birthday) values("用户",20,NOW());

insert into page(user_name,user_age,birthday) select user_name,user_age,birthday from page (插入的数据呈几何倍数增长,快速插入上万条数据记录)

update page set user_name = concat(user_name,user_id);

2、在eclipse或者IDEA中创建一个Java Web项目

在这里我以eclipse为例,创建web项目(page),目录结构如下():
分页技术实现

2.1、实体类

public class User {
	private Integer userId;
	private String userName;
	private Integer age;
	private Time birthday;
}  //setter and getter ...

2.2、dao层

package com.chang.dao;

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

import com.chang.entity.User;
import com.chang.utils.DBUtils;

public class UserDao {

	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	
	//查询全部学生信息
	public List<User> getList(){
		String sql = "select * from page";
		List<User> list = new ArrayList<>();
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while(rs.next()) {
				User user = new User();
				user.setUserId(rs.getInt("user_id"));
				user.setUserName(rs.getString("user_name"));
				user.setAge(rs.getInt("user_age"));
				user.setBirthday(rs.getTime("birthday"));
				list.add(user);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBUtils.close(conn, ps, rs);
		}
		return list;
	}
}

(说明:DBUtils是我对JDBC数据库连接的封装,也可以不用封装完成对JDBC数据库的连接,注意导入MySQL的驱动包)

2.3、servlet编写

package com.chang.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.chang.dao.UserDao;
import com.chang.entity.User;


public class PageServlet extends HttpServlet {

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

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//当前1/333页|上一页|下一页|尾页|共6666条|每页20条
		List<User> list = new UserDao().getList();
		int pageSize = 20;//定义每页20条数据
		int totalCount = list.size();  //定义数据总条数
		int totalPage;//定义总页数
		int pageNo = 0;;//定义当前页数
		String _pageNo = request.getParameter("pageNo");
		if(_pageNo == null) {
			pageNo = 1;
		}else {
			pageNo = Integer.parseInt(_pageNo);
		}
		if(totalCount % pageSize == 0) {
			totalPage = (totalCount/pageSize);
		}else {
			totalPage = (totalCount/pageSize)+1;
		}
	
		boolean firstPage = false;
		boolean lastPage = false;
		int prePage = 0;
		int nextPage = 0;
		if(pageNo == 1) {
			firstPage = true;
		}
		if(pageNo == totalPage) {
			lastPage = true;
		}
		if(firstPage) {
			prePage = 1;
		}else {
			prePage = pageNo-1;
		}
		if(lastPage) {
			nextPage = totalPage;
		}else {
			nextPage = pageNo+1;
		}
		
		List<User> newList = new ArrayList();
		int index = 0;
		for (User user : list) {
			index++;
			if(index >= ((pageNo-1)*pageSize+1) && (index <= (pageNo*pageSize))) {
				newList.add(user);
			}
		}
		
		request.setAttribute("pageSize",pageSize);
		request.setAttribute("totalPage",totalPage);
		request.setAttribute("totalCount",totalCount);
		request.setAttribute("pageNo",pageNo);
		request.setAttribute("list",newList);
		request.setAttribute("prePage",prePage);
		request.setAttribute("nextPage",nextPage);
		RequestDispatcher dis = request.getRequestDispatcher("index.jsp");
		dis.forward(request, response);
	}
}

2.4、web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>page</display-name>
  <servlet>
        <servlet-name>page</servlet-name>
        <servlet-class>com.chang.servlet.PageServlet</servlet-class>
  </servlet>
  <servlet-mapping>
        <servlet-name>page</servlet-name>
        <url-pattern>/page</url-pattern>
  </servlet-mapping>
</web-app>

2.5、展示层

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>分页技术实现</title>
<style type="text/css">
	a{
		color: blue;	
	}
</style>
</head>
<body>
当前${pageNo}/${totalPage}页|
<a href="page?pageNo=1">首页</a>
<a href="page?pageNo=${prePage}">上一页|</a>
<a href="page?pageNo=${nextPage}">下一页|</a>
<a href="page?pageNo=${totalPage}">尾页|</a>
共${totalCount}条|每页${pageSize}条
<table border="2" width="700px">
	<tr align="center">
		<th>ID</th>
		<th>姓名</th>
		<th>年龄</th>
		<th>出生日期</th>
	</tr>
	<c:forEach items="${list}" var="user">
	<tr align="center">
		<td>${user.userId}</td>
		<td>${user.userName}</td>
		<td>${user.age}</td>
		<td>${user.birthday}</td>
	</tr>
	</c:forEach>
</table>
</body>
</html>

3、内存分页的流程梳理和总结

通过上边的学习,相信对相关的分页知识有了一定的了解,那么接下来我将再次梳理一下上边的思路。

数据库设计

​ 先创建一张表,注意user_id要设置成自动增长,然后往表中插入几千条甚至上万条数据都行。当然数据越多越好,尽量控制在不超过三万条记录,方便我们对后边的数据库分页进行性能对比。

开发工具创建web项目

​ 开发工具创建web项目,然后部署到tomcat进行测试,跑成功以后开始下边的程序设计(防止程序写完项目不能正常运行)。

​ 首先我们要创建实体类,对应我们创建的数据库。接下来是创建我们的dao层,在dao层要实现查找全部信息的功能,把从数据库中查找出来的数据存放在List集合中,等我们在servlet中调用使用。

​ dao层写完之后,我们要进行servlet的创建,我这里使用的配置web.xml的方式,没有使用注解。配置完servlet便可以开始业务逻辑的编写,下边的内容将是解决内存分页技术的关键。

分页变量和思路

​ 首先我们需要需要的servlet中取出存放在dao中的数据库表中的信息,然后定义一个List集合进行接收,接收完成之后存放在请求作用域(request.setAttribut())中,通过jsp标签遍历输出到展示层。

​ 但是接下来我们会发现,一个网页中取出了我们数据库中的所有信息,需要我们不停的下拉滚动条才能浏览,很是不方便,接下来我们将用分页技术来解决这一尴尬的局面。

​ 要想实现我们的分页,需要定义几个变量:

pageNo : 当前页码((pageNo - 1) - 1 * pageSize + 1)

totalPage : 总页码(如果totalCount % pageSize == 0 那么 totalpage = totalCount/pageSize 否则 totalpage = totalCount/pageSize + 1)。

totalCount : 数据库数据总条数(我们已经把数据存放在List集合中,因此可以通过list.size()取得数据总数)

pageSize : 每页固定要显示的数据数量(可自定义)

firstPage : 首页(如果pageNo = 1,那么这就是第一页,firstPage = pageNo)

lastPage : 尾页(如果pageNo = totalPage,那么这就是最后一页,即lastPage = pageNo)

prePage : 上一页(如果firstPage = 1,那么prePage = firstPage,否则prePage - 1)

nextPage : 下一页(如果lastPage = totalPage,那么nextPage = lastPage,否则nextPage + 1)

​ 当了解了上边的思路,结合servlet中的业务逻辑代码应该就能解决分页的业务逻辑问题,接下来把上比的变量全部存放在作用域中,在展示层通过jsp标签进行遍历读取。

总结

​ 分页技术是我们进行web开发中的必备技能,同时学起来也不是特别的困难,相信通过分页技术的学习,一定会让你在今后的Java学习道路中越走越远,加油!

tPage = 1,那么prePage = firstPage,否则prePage - 1)

nextPage : 下一页(如果lastPage = totalPage,那么nextPage = lastPage,否则nextPage + 1)

​ 当了解了上边的思路,结合servlet中的业务逻辑代码应该就能解决分页的业务逻辑问题,接下来把上比的变量全部存放在作用域中,在展示层通过jsp标签进行遍历读取。

总结

​ 分页技术是我们进行web开发中的必备技能,同时学起来也不是特别的困难,相信通过分页技术的学习,一定会让你在今后的Java学习道路中越走越远。下期我将继续更新数据库分页的实现以及对分页进行封装。我也是一名在校的学生,在Java的学习道路上还有很长的道路要走,第一次写博客,可能写的不是太好,如果觉得我的代码什么的u偶问题,欢迎大家批评指正。qq:2269673232

上一篇:SpringBoot Jpa入门案例


下一篇:【MyBatis&MyBatis-plus】分页查询避免两次查询同时返回总数和数据