如果您不熟悉使用 Tomcat 和 Eclipse 开发 Servlet,则可以在继续本示例之前阅读此页面。

分页逻辑可以通过多种方式实现,有些是
方法一:贪婪方法
方法2:非贪婪方法
我们使用第二种方法来演示分页。
本示例使用一张 Employee 表,该表的描述如下所示。
“员工”表
| FIELD | TYPE | KEY | EXTRA |
|---|---|---|---|
| emp_id | int | Primary Key | auto_increment |
| emp_name | varchar(255) | ||
| salary | double | ||
| dept_name | varchar(255) |
mysql -u [你的用户名] -p
然后按回车键并输入密码。

Employee.java 类
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package com.theopentutorials.to;
public class Employee {
private int employeeId;
private String employeeName;
private double salary;
private String deptName;
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
|
在编写 DAO 类之前,让我们编写一个 ConnectionFactory 类,它具有数据库连接配置语句和连接数据库的方法。此类使用单例模式。
在 src 文件夹中创建一个新包并将其命名为com.theopentutorials.db并复制以下代码。
ConnectionFactory.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package com.theopentutorials.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionFactory {
//static reference to itself
private static ConnectionFactory instance =
new ConnectionFactory();
String url = "jdbc:mysql://localhost/exampledb";
String user = "<YOUR_DATABASE_USERNAME>";
String password = "<YOUR_DATABASE_PASSWORD>";
String driverClass = "com.mysql.jdbc.Driver";
//private constructor
private ConnectionFactory() {
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static ConnectionFactory getInstance() {
return instance;
}
public Connection getConnection() throws SQLException,
ClassNotFoundException {
Connection connection =
DriverManager.getConnection(url, user, password);
return connection;
}
}
|
填写数据库的用户名和密码,并在 url 字符串中输入您的数据库名称。
此类使用封装了对数据源的访问的数据访问对象 (DAO) 模式。
EmployeeDAO.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
package com.theopentutorials.dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.theopentutorials.db.ConnectionFactory;
import com.theopentutorials.to.Employee;
public class EmployeeDAO {
Connection connection;
Statement stmt;
private int noOfRecords;
public EmployeeDAO() { }
private static Connection getConnection()
throws SQLException,
ClassNotFoundException
{
Connection con = ConnectionFactory.
getInstance().getConnection();
return con;
}
public List<Employee> viewAllEmployees(
int offset,
int noOfRecords)
{
String query = "select SQL_CALC_FOUND_ROWS * from employee limit "
+ offset + ", " + noOfRecords;
List<Employee> list = new ArrayList<Employee>();
Employee employee = null;
try {
connection = getConnection();
stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
employee = new Employee();
employee.setEmployeeId(rs.getInt("emp_id"));
employee.setEmployeeName(rs.getString("emp_name"));
employee.setSalary(rs.getDouble("salary"));
employee.setDeptName(rs.getString("dept_name"));
list.add(employee);
}
rs.close();
rs = stmt.executeQuery("SELECT FOUND_ROWS()");
if(rs.next())
this.noOfRecords = rs.getInt(1);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally
{
try {
if(stmt != null)
stmt.close();
if(connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
public int getNoOfRecords() {
return noOfRecords;
}
}
|
一个 SELECT 语句可能包含一个LIMIT 子句来限制服务器返回给客户端的行数。这个 LIMIT 子句有两个参数;第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。
在某些情况下,希望知道在没有 LIMIT 的情况下该语句将返回多少行,但无需再次运行该语句。要获取此行数,请在 SELECT 语句中包含SQL_CALC_FOUND_ROWS选项,然后调用FOUND_ROWS():
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package com.theopentutorials.servlets;
import java.io.IOException;
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.theopentutorials.dao.EmployeeDAO;
import com.theopentutorials.to.Employee;
/**
* Servlet implementation class EmployeeServlet
*/
public class EmployeeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public EmployeeServlet() {
super();
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
int page = 1;
int recordsPerPage = 5;
if(request.getParameter("page") != null)
page = Integer.parseInt(request.getParameter("page"));
EmployeeDAO dao = new EmployeeDAO();
List<Employee> list = dao.viewAllEmployees((page-1)*recordsPerPage,
recordsPerPage);
int noOfRecords = dao.getNoOfRecords();
int noOfPages = (int) Math.ceil(noOfRecords * 1.0 / recordsPerPage);
request.setAttribute("employeeList", list);
request.setAttribute("noOfPages", noOfPages);
request.setAttribute("currentPage", page);
RequestDispatcher view = request.getRequestDispatcher("displayEmployee.jsp");
view.forward(request, response);
}
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="Java EE: XML Schemas for Java EE Deployment Descriptors http://java.sun.com/xml/ns/javae
/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>JSPPagination</display-name>
<servlet>
<servlet-name>EmployeeServlet</servlet-name>
<servlet-class>com.theopentutorials.servlets.EmployeeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EmployeeServlet</servlet-name>
<url-pattern>/employee.do</url-pattern>
</servlet-mapping>
</web-app>
|
此 JSP 页面使用 JSP 标准标记库 (JSTL) 以及表达式语言 (EL)。它从请求范围检索属性并显示结果。要使用 JSTL 库,您必须在 JSP 页面中包含 <taglib> 指令。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="Oracle Java Technologies | Oracle" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Employees</title>
</head>
<body>
<table border="1" cellpadding="5" cellspacing="5">
<tr>
<th>Emp ID</th>
<th>Emp Name</th>
<th>Salary</th>
<th>Dept Name</th>
</tr>
<c:forEach var="employee" items="${employeeList}">
<tr>
<td>${employee.employeeId}</td>
<td>${employee.employeeName}</td>
<td>${employee.salary}</td>
<td>${employee.deptName}</td>
</tr>
</c:forEach>
</table>
<%--For displaying Previous link except for the 1st page --%>
<c:if test="${currentPage != 1}">
<td><a href="employee.do?page=${currentPage - 1}">Previous</a></td>
</c:if>
<%--For displaying Page numbers.
The when condition does not display a link for the current page--%>
<table border="1" cellpadding="5" cellspacing="5">
<tr>
<c:forEach begin="1" end="${noOfPages}" var="i">
<c:choose>
<c:when test="${currentPage eq i}">
<td>${i}</td>
</c:when>
<c:otherwise>
<td><a href="employee.do?page=${i}">${i}</a></td>
</c:otherwise>
</c:choose>
</c:forEach>
</tr>
</table>
<%--For displaying Next link --%>
<c:if test="${currentPage lt noOfPages}">
<td><a href="employee.do?page=${currentPage + 1}">Next</a></td>
</c:if>
</body>
</html>
|
第一个“表”标签显示员工列表及其详细信息。第二个“表”标签显示页码。
此示例的完整文件夹结构如下所示。

在 Eclipse 中使用 Ctrl + F11 来运行 Servlet。请求 Servlet 的 URL 是
http://localhost:8080/JSPPagination/employee.do

