本文適合於初學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中,只需要做一個簡單的判斷就行。
上面的訪問截圖可能和發的代碼中的有點不一樣,是因爲我後面又加上了刪除、新增和按條件查詢幾個小功能。
本文章是我在學習過程中的一點理解,如果有寫的不好的地方請大家多多包涵,希望大家提出自己寶貴的意見促使我更進一步,謝謝大家。