1、前言
最近在写一些项目,遇到要使用分页功能的地方,就简单的学习了一下,在此总结一下具体实现的过程以及遇到的问题。
分页功能:当我们写一下web项目时会遇到一个页面要显示很多数据,一下子都显示出来效率会很低,也不美观。这就要用到分页,其作用也就是将数据分割成多个页面来进行显示。
2、项目介绍
这只是一个简单的Demo,目的是学习分页功能的实现。
涉及的技术:
Java基础知识,HTML, CSS, JAVASCRIPT, JQUERY,Tomcat, Servlet, JSP, Filter,Mysql
项目预览:
项目结构:
3、实现步骤
(1)打开IDEA创建一个Web项目
(2)创建一个数据库,因为只是展示分页功能,显示一个表就行了,所以创建一个表就行了。然后在随便插一些数据
数据库名:student
表名:student
(3)导包
项目中用到的jar包(zi2t):
jstl.jar
mysql-connector-java-8.0.16.jar
standard.jar
(4)实体类设计,与student表字段对应
在bean包中创建一个student类
package com.sun.bean;
import java.util.Date;
public class Student {
private int id;
private int studentID;
private String name;
private int age;
private String sex;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getStudentID() {
return studentID;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
(5)在Utils包下创建连接数据库的工具类
package com.sun.Utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
static String ip = "127.0.0.1";
static int port = 3306;
static String database = "student";
static String encoding = "UTF-8";
static String loginName = "root";
static String password = "123456";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
String url = String.format("jdbc:mysql://%s:%d/%s?characterEncoding=%s&serverTimezone=UTC", ip, port, database, encoding);
return DriverManager.getConnection(url, loginName, password);
}
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
}
(6)在Utils包下创建用于分页功能的工具类
package com.sun.Utils;
public class Page {
int start; // 开始数据
int count; // 每一页的数量
int total; // 总共的数据量
public Page(int start, int count) {
super();
this.start = start;
this.count = count;
}
public boolean isHasPreviouse(){
if(start==0)
return false;
return true;
}
public boolean isHasNext(){
if(start==getLast())
return false;
return true;
}
public int getTotalPage(){
int totalPage;
// 假设总数是50,是能够被5整除的,那么就有10页
if (0 == total % count)
totalPage = total /count;
// 假设总数是51,不能够被5整除的,那么就有11页
else
totalPage = total / count + 1;
if(0==totalPage)
totalPage = 1;
return totalPage;
}
public int getLast(){
int last;
// 假设总数是50,是能够被5整除的,那么最后一页的开始就是40
if (0 == total % count)
last = total - count;
// 假设总数是51,不能够被5整除的,那么最后一页的开始就是50
else
last = total - total % count;
last = last<0?0:last;
return last;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}
(7)在dao包下创建一个studentDAO类,里面有一个查询学生列表的方法。因为功能简单就只写了查询功能。
package com.sun.dao;
import com.sun.Utils.DBUtil;
import com.sun.bean.Student;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class StudentDao {
public int getTotal() {
int total = 0;
String sql = "SELECT COUNT(*) FROM student";
try (Connection c = DBUtil.getConnection(); Statement st = c.createStatement()) {
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
total = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return total;
}
public List<Student> list() {
return list(0, Short.MAX_VALUE);
}
public List<Student> list(int start, int count) {
List<Student> students = new ArrayList<>();
String sql = "SELECT * FROM student ORDER BY studentID limit ?,?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {
ps.setInt(1, start);
ps.setInt(2, count);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Student student = new Student();
int id = rs.getInt("id");
int studentID = rs.getInt("studentID");
String name = rs.getString("name");
int age = rs.getInt("age");
String sex = rs.getString("sex");
Date birthday = rs.getDate("birthday");
student.setId(id);
student.setStudentID(studentID);
student.setName(name);
student.setAge(age);
student.setSex(sex);
student.setBirthday(birthday);
students.add(student);
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
return students;
}
}
(8)由于项目中设计表单 POST 方式的提交,所以我们先来编写好相关编码的过滤器,好支持中文的存取
在filter包 下编写 EncodingFilter 类:
package com.sun.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.dsig.spec.XPathType;
import java.io.IOException;
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 设置编码格式为 UTF-8
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
}
}
(9)编写servlet对应查询功能,在servlet包下创建ListServlet:
package com.sun.servlet;
import com.sun.Utils.Page;
import com.sun.bean.Student;
import com.sun.dao.StudentDao;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet(name = "ListServlet", urlPatterns="/ListServlet")
public class ListServlet extends HttpServlet {
private StudentDao studentDao = new StudentDao();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取分页参数
int start = 0;
int count = 5;
try {
start = Integer.parseInt(request.getParameter("page.start"));
count = Integer.parseInt(request.getParameter("page.count"));
} catch (Exception e) {
e.printStackTrace();
}
Page page = new Page(start, count);
List<Student> students = studentDao.list(page.getStart(), page.getCount());
int total = studentDao.getTotal();
page.setTotal(total);
request.setAttribute("students", students);
request.setAttribute("page", page);
request.getRequestDispatcher("/listStudents.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
(10)前端页面jsp的设计
为了简化操作,引入了 JQuery 和 Bootstrap,相关js css文件在这里(zi2t )。
在web文件夹下编写ListStudent.jsp
<%--
Created by IntelliJ IDEA.
User: sunshengwei-pc
Date: 2020/3/10
Time: 17:29
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<%-- 引入JQ和Bootstrap --%>
<script src="js/jquery-2.0.3.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<link href="css/style.css" rel="stylesheet">
<title>学生列表</title>
<script>
$(function () {
$("ul.pagination li.disabled a").click(function () {
return false;
});
});
</script>
</head>
<body>
<div class="listDIV">
<table class="table table-striped table-bordered table-hover table-condensed">
<caption>学生列表 - 共${page.total}人</caption>
<thead>
<tr class="success">
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>出生日期</th>
</tr>
</thead>
<tbody>
<c:forEach items="${students}" var="s" varStatus="status">
<tr>
<td>${s.studentID}</td>
<td>${s.name}</td>
<td>${s.age}</td>
<td>${s.sex}</td>
<td>${s.birthday}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<nav class="pageDIV">
<ul class="pagination">
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=0">
<span>首页</span>
</a>
</li>
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=${page.start-page.count}">
<span>上一页</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<c:if test="${status.count*page.count-page.start<=30 && status.count*page.count-page.start>=-10}">
<li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
<a
href="?page.start=${status.index*page.count}"
<c:if test="${status.index*page.count==page.start}">class="current"</c:if>
>${status.count}</a>
</li>
</c:if>
</c:forEach>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.start+page.count}">
<span>下一页</span>
</a>
</li>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.last}">
<span>尾页</span>
</a>
</li>
</ul>
</nav>
</body>
</html>
(11)启动Tomcat,在浏览器地址栏输入:http://localhost:8080/ListServlet
4、总结
(1)访问servlet时404:我用的是注解扫描servlet,刚开始是这样写的@WebServlet(name = “ListServlet”),怎么也访问不到,加上 urlPatterns="/ListServlet"就可以访问到了。当然也可以不用注解的方式,但是要在web.xml中配置:
<filter><!-- 过滤器配置-->
<filter-name>EncodingFilter</filter-name>
<filter-class>com.sun.filter.EncodingFilter</filter-class><!--全路径 从根包开始一直到类名-->
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/ *</url-pattern> <!--*即为过滤所有-->
</filter-mapping>
<servlet><!--servlet类路径配置-->
<servlet-name>ListServlet</servlet-name>
<servlet-class>com.sun.servlet.ListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListServlet</servlet-name>
<url-pattern>/ListServlet</url-pattern>
</servlet-mapping>
<welcome-file-list><!--默认首页地址-->
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
(2)可以访问servlet后,又访问不到jsp文件。原来我犯了一个低级错误,也是刚学web项目时容易犯的错误:不应该把页面写在WEB-INF文件夹下,因为在这个文件夹下不能直接访问。
(3)连接数据库时报错,时区的问题在url中加上&serverTimezone=UTC就可以了。
想要项目全部源码的童鞋们可以发邮件给我啦,有什么问题欢迎在评论区留言。
Email:15638186609@163.com