本文适合于初学jsp和servlet的,是一个简单分页的教程,不考虑到代码的优化和SQL优化。
项目使用数据库版本MySQL5.7,数据表为student表,表数据及结构如下:
分页原理:利用MySQL数据库的“select * from student limit ?,?”语句实现分页,代码中第一个问号表示查询的数据开始位,第二个问号表示查询的数据条数,在MySQL中数据的索引是从0开始,例如每页显示三条数据,那么第一页的SQL代码为:select * from student limit 0,3; 第二页的SQL代码为:select * from student limit 3,3;下图为每页的页码、数据开始位置和数据条数之间的关系:
根据图中关系可得知,数据开始位置为:(页码-1)*数据条数,设页码为currentPage,每页显示数据条数为pageSize,可得出通用SQL语句为:select * from student limit (currentPage-1)*currentPage,pageSize;
SQL语句确定了,但是页码和每页显示的数据条数怎么确定呢?页码即为当前页码,当用户第一次打开浏览器时默认的页码为1,当用户点击上一页或者下一页时,页码自动减1或者加1。而每页显示的数据条数可以是系统规定好或者是从jsp页面获取到用户自定义的每页显示数据条数。
除了当前页码,显示数据条数之外,还需要拿到的数据就是数据库数据总条数,数据总条数可以使用SQL语句:select count(*) from student; 得到,设数据总条数为totalCount,那么总页数为:总数据条数除以每页显示的数据条数,设总页数为total Page,则:totalPage=totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1; (当除了之后不为整数则多用一页来显示剩余信息)
本文使用了Student实体类来封装传递学生信息,和Page实体类封装传递当前页码,每页显示数据条数,每页显示的数据信息,总页数和总数据数。
步骤:
第一步、编写DBUtil数据库帮助类,代码如下:
package com.lee.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBUtil {
private static final String URL = "jdbc:mysql://localhost:3306/lee?useUnicode=true&characterEncoding=utf-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
public static Connection con = null;
public static PreparedStatement pstmt = null;
public static ResultSet rs = null;
//获取链接
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(URL,USERNAME,PASSWORD);
}
//获取PreparedStatement
public static PreparedStatement createPstmt(String sql,Object[] params) throws ClassNotFoundException, SQLException {
pstmt = getConnection().prepareStatement(sql);
if(params != null) {
for(int i = 0; i < params.length; i++) {
pstmt.setObject(i+1, params[i]);
}
}
return pstmt;
}
//关闭数据库
public static void closeAll(ResultSet rs, Statement stmt, Connection con) {
try {
if(rs != null)
rs.close();
if(stmt != null)
stmt.close();
if(con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据总数
public static int getCount(String sql) {
int count = -1;
try {
pstmt = createPstmt(sql, null);
rs = pstmt.executeQuery();
if(rs.next())
count = rs.getInt(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeAll(rs, pstmt, con);
}
return count;
}
//通用查询
public static ResultSet executeQuery(String sql, Object[] params) {
try {
pstmt = createPstmt(sql,params);
return pstmt.executeQuery();
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
第二步、编写Dao层调用数据库,代码如下:
package com.lee.dao.impl;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import com.lee.dao.IStudentDao;
import com.lee.entity.Student;
import com.lee.util.DBUtil;
public class StudentDaoImpl implements IStudentDao {
//查询总数据数
public int getCount() {
String sql = "select count(*) from student";
return DBUtil.getCount(sql);
}
//查询每页显示的学生个数
public List<Student> queryStudentByPage(int currentPage,int pageSize){
String sql = "select * from student limit ?,?";
List<Student> students = new ArrayList<>();
Student student = null;
Object[] params = {(currentPage-1)*pageSize,pageSize};
ResultSet rs = DBUtil.executeQuery(sql, params);
try {
while(rs.next()) {
int no = rs.getInt("no");
String name = rs.getString("name");
int age = rs.getInt("age");
String address = rs.getString("address");
student = new Student(no,name,age,address);
students.add(student);
}
} catch (SQLException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
} finally {
DBUtil.closeAll(rs, DBUtil.pstmt, DBUtil.con);
}
return students;
}
}
第三步、编写service服务层调用Dao层,代码如下:
package com.lee.service.impl;
import java.util.List;
import com.lee.dao.IStudentDao;
import com.lee.dao.impl.StudentDaoImpl;
import com.lee.entity.Student;
import com.lee.service.IStudentService;
public class StudentServiceImpl implements IStudentService {
IStudentDao studentDao = new StudentDaoImpl();
//查询数据总数
public int getCount() {
return studentDao.getCount();
}
//查询每页显示的学生的信息
public List<Student> queryStudentByPage(int currentPage, int pageSize) {
return studentDao.queryStudentByPage(currentPage, pageSize);
}
}
第四步:编写servlet控制层,代码如下:
package com.lee.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.lee.entity.Page;
import com.lee.entity.Student;
import com.lee.service.IStudentService;
import com.lee.service.impl.StudentServiceImpl;
public class QueryStudentByPage extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
IStudentService studentService = new StudentServiceImpl();
int count = studentService.getCount();
Page page = new Page();
String cPage = request.getParameter("currentPage");
if(cPage == null)
cPage = "1";
int currentPage = Integer.parseInt(cPage);
String cPageSize = request.getParameter("pageSize");
if(cPageSize == null)
cPageSize = "3";
int pageSize = Integer.parseInt(cPageSize);
List<Student> students = studentService.queryStudentByPage(currentPage, pageSize);
page.setTotalCount(count);
page.setPageSize(pageSize);
page.setStudent(students);
page.setCurrentPage(currentPage);
request.setAttribute("page", page);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
第五步:编写jsp显示层,代码如下:
<%@page import="com.lee.entity.Page"%>
<%@page import="java.util.List"%>
<%@page import="com.lee.entity.Student"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>首页</title>
<style>
td{
width:100px;
}
th{
width:100px;
}
</style>
</head>
<body>
<h2>学生信息列表</h2>
<table border="1">
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
<%
Page sPage = (Page)request.getAttribute("page");
for(Student student : sPage.getStudent()){
%>
<tr>
<td><%=student.getNo() %></td>
<td><%=student.getName() %></td>
<td><%=student.getAge() %></td>
<td><%=student.getAddress() %></td>
</tr>
<%
}
%>
</table>
<br>
<%
if(sPage.getCurrentPage() == sPage.getTotalPage()){
%>
<a href="QueryStudentByPage?currentPage=1&pageSize=<%=sPage.getPageSize()%>">首页</a>
<a href="QueryStudentByPage?currentPage=<%=sPage.getCurrentPage()-1%>&pageSize=<%=sPage.getPageSize()%>">上一页</a>
<%
}else if(sPage.getCurrentPage() == 1){
%>
<a href="QueryStudentByPage?currentPage=<%=sPage.getCurrentPage()+1%>&pageSize=<%=sPage.getPageSize()%>">下一页</a>
<a href="QueryStudentByPage?currentPage=<%=sPage.getTotalPage()%>&pageSize=<%=sPage.getPageSize()%>">尾页</a>
<%
}else{
%>
<a href="QueryStudentByPage?currentPage=1">首页</a>
<a href="QueryStudentByPage?currentPage=<%=sPage.getCurrentPage()-1%>&pageSize=<%=sPage.getPageSize()%>">上一页</a>
<a href="QueryStudentByPage?currentPage=<%=sPage.getCurrentPage()+1%>&pageSize=<%=sPage.getPageSize()%>">下一页</a>
<a href="QueryStudentByPage?currentPage=<%=sPage.getTotalPage()%>&pageSize=<%=sPage.getPageSize()%>">尾页</a>
<%
}
%>
<br>
<form action="QueryStudentByPage">
每页显示
<select name="pageSize">
<option value="3">3</option>
<option value="5">5</option>
<option value="7">7</option>
<option value="10">10</option>
</select>
条数据
<input type="submit" value="确定">
</form>
</body>
</html>
第六步、编写web.xml,在打开浏览器的时候先访问servlet,然后从servlet转发到jsp,防止直接访问jsp数据列表为空,只需要在web.xml中配置如下代码即可,其他在web.xml中配置的servlet映射自行配置。
<welcome-file-list>
<welcome-file>QueryStudentByPage</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
所有代码写完之后就可以在浏览器中访问项目地址即可:
其中首页中不显示首页和上一页以及尾页中不显示尾页和下一页的代码都在JSP中,只需要做一个简单的判断就行。
上面的访问截图可能和发的代码中的有点不一样,是因为我后面又加上了删除、新增和按条件查询几个小功能。
本文章是我在学习过程中的一点理解,如果有写的不好的地方请大家多多包涵,希望大家提出自己宝贵的意见促使我更进一步,谢谢大家。