分页概述
分页是一个很常见的一个技术,具体的效果如下图所示:
如果需要完整项目可以浏览链接:ThreeTierSample.zip
提取码:8gwz
实现
第一步写一个Page实体类(PS:这个实体类其实就是一个javaBean,不知道什么是Javabean的同学可以参见什么是JavaBean?.),用于传输信息:
package org.student.entity;
import java.util.List;
public class MyPage {
// 当前页 currentPage
private int currentPage;
// 页面大小 pageSize
private int pageSize ;
// 总数据 totalCount
private int totalCount;
// 总页数 totalPage
private int totalPage ;
// 当前页的数据集合 students
private List<Student> students;
public MyPage() {
}
public MyPage(int currentPage, int pageSize, int totalCount, int totalPage, List<Student> students) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.totalCount = totalCount;
this.totalPage = totalPage;
this.students = students;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
/*
* 总页数 = 数据总数%页面大小==0? 数据总数/页面大小:数据总数/页面大小+1 ;
*
* 当我们调换用了 数据总数的set() 和 页面大小的set()以后,自动计算出 总页数
* 务必注意顺序:先set 数据总数 再set 页面大小
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
//自动计算出 总页数
// 总页数 = 数据总数%页面大小==0? 数据总数/页面大小:数据总数/页面大小+1 ;
this.totalPage =this.totalCount%this.pageSize==0?this.totalCount/this.pageSize:totalCount/this.pageSize+1;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPage() {
return totalPage;
}
//给总页数赋值
// public void setTotalPage(int totalPage) {
// this.totalPage = totalPage;
// }
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
1.JSP(表现层的前端代码)
<%@page import="org.student.entity.Student"%>
<%@page import="org.student.entity.MyPage"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("tr:odd").css("background-color","lightgray");
});
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>学生信息列表</title>
</head>
<body>
<%
//error:adderror 失败
//否则:1 确实执行了增加 2直接访问查询全部页面
String error = (String)request.getAttribute("error") ;//addError
if(error!=null){
if(error.equals("addError")){
out.print("增加失败!");
}else if(error.equals("noaddError")){
out.print("增加成功!");
}//根本没有执行增加
}
%>
<table border="1px">
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>操作</th>
</tr>
<%
//获取request域中的数据Page p = (Page)request.getAttribute("p") ;
MyPage myPage = (MyPage)request.getAttribute("p");
List<Student> students = myPage.getStudents();
for(Student student:students){
%>
<tr>
<td><a href="QueryStudentBysIdServlet?sId=<%=student.getsId() %>"><%=student.getsId() %></a> </td>
<td><%=student.getsName()%></td>
<td><%=student.getsGender() %></td>
<td> <a href="DeleteStudentServlet?sId=<%=student.getsId() %> ">删除</a> </td>
</tr>
<%
}
%>
</table>
<%
out.print(myPage.getCurrentPage());
out.print(myPage.getTotalPage());
if(myPage.getCurrentPage() == myPage.getTotalPage()){ //尾页
%> <a href="QueryStudentByPage?currentPage=0">首页</a>
<a href="QueryStudentByPage?currentPage=<%=myPage.getCurrentPage()-1%> ">上一页</a>
<%
}
else if(myPage.getCurrentPage() ==0){//首页
%> <a href="QueryStudentByPage?currentPage=<%=myPage.getCurrentPage()%> ">下一页</a>
<a href="QueryStudentByPage?currentPage=<%=myPage.getTotalPage()%>">尾页</a>
<%
}
else{//中间
%>
<a href="QueryStudentByPage?currentPage=0">首页</a>
<a href="QueryStudentByPage?currentPage=<%=myPage.getCurrentPage()-1%> ">上一页</a>
<a href="QueryStudentByPage?currentPage=<%=myPage.getCurrentPage()+1%> ">下一页</a>
<a href="QueryStudentByPage?currentPage=<%=myPage.getTotalPage()%>">尾页</a>
<%
}
%>
<br/>
每页显示
<select>
<option value="3">3</option>
<option value="5">5</option>
<option value="10">10</option>
</select>
条
<a href="Add.jsp">新增</a>
</body>
</html>
2.servlet(表现层/Controller的后端代码):
package org.student.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 org.student.dao.StudentDao;
import org.student.dao.Impl.StudentDaoImpl;
import org.student.entity.MyPage;
import org.student.entity.Student;
import org.student.service.StudentService;
import org.student.service.impl.StudentServiceImpl;
/**
* Servlet implementation class QueryStudentByPage
*/
public class QueryStudentByPage extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StudentService studentService = new StudentServiceImpl();
int count = studentService.getTotalCount() ;//数据总数
//将分页所需的5个字段(其中有1个自动计算,因此实际只需要组装4个即可),组装到page对象之中
MyPage myPage = new MyPage();
System.out.println(myPage);
String cPage = request.getParameter("currentPage") ;//
if(cPage == null) {
cPage = "0" ;
}
System.out.println(cPage);
int currentPage = Integer.parseInt( cPage );
myPage.setCurrentPage(currentPage);
// int currentPage = 2;//页码
//注意 顺序
int totalCount = studentService.getTotalCount() ;//总数据数
System.out.println(totalCount);
myPage.setTotalCount(totalCount);
/* currentPage:当前页(页码)
students :当前页的数据集合(当前页的所有学生)
*/
int pageSize = 3;
myPage.setPageSize(pageSize);
List<Student> students = studentService.queryStudentsByPage(currentPage, pageSize) ;
System.out.println(count);
myPage.setStudents(students);
request.setAttribute("p", myPage);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.控制器(三层架构的Service层/业务逻辑层)
package org.student.service.impl;
import java.util.List;
import org.junit.Test;
import org.student.dao.StudentDao;
import org.student.dao.Impl.StudentDaoImpl;
import org.student.entity.Student;
import org.student.service.StudentService;
//业务逻辑层:逻辑性的增删改查(增=查+增),对dao层进行组装
public class StudentServiceImpl implements StudentService {
StudentDao studentDao = new StudentDaoImpl();
@Override
public List<Student> queryStudentsByPage(int currentPage, int pageSize) {
// TODO Auto-generated method stub
return studentDao.queryStudentsByPage(currentPage, pageSize);
}
}
JDBC(数据访问层/DAO层)
package org.student.dao.Impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.student.dao.StudentDao;
import org.student.entity.Student;
import org.student.util.DBUtil;
public class StudentDaoImpl implements StudentDao{
public List<Student> queryAllStudents() {
PreparedStatement pstmt = null ;
Student student = null;
List<Student> students = new ArrayList<>();
ResultSet rs = null ;
try {
String sql = "select * from student" ;
rs = DBUtil.executeQuery(sql, null) ;
while(rs.next()) {
int sId = rs.getInt("sId") ;
String sName = rs.getString("sName") ;
String sGender = rs.getString("sGender");
String sAddress = rs.getString("sAddress") ;
student = new Student(sId, sName, sGender, sAddress);
students.add(student) ;
}
return students ;
} catch (SQLException e) {
e.printStackTrace();
return null ;
}catch (Exception e) {
e.printStackTrace();
return null ;
}
finally {
DBUtil.closeAll(rs, pstmt, DBUtil.connection);
}
}
public List<Student> queryStudentsByPage(int currentPage, int pageSize) {
PreparedStatement pstmt = null ;
Student student = null;
List<Student> students = new ArrayList<>();
ResultSet rs = null ;
try {
String sql = "SELECT * FROM student LIMIT ?,? ;" ;
Object[] params = {currentPage*pageSize , pageSize};
rs = DBUtil.executeQuery(sql, params) ;
while(rs.next()) {
int sId = rs.getInt("sId") ;
String sName = rs.getString("sName") ;
String sGender = rs.getString("sGender");
String sAddress = rs.getString("sAddress") ;
student = new Student(sId, sName, sGender, sAddress);
students.add(student) ;
}
return students ;
} catch (SQLException e) {
e.printStackTrace();
return null ;
}catch (Exception e) {
e.printStackTrace();
return null ;
}
finally {
DBUtil.closeAll(rs, pstmt, DBUtil.connection);
}
}
}
JDBC工具类(DBUtil.java)
package org.student.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;
import java.util.ArrayList;
import java.util.List;
import org.student.entity.Student;
//通用的数据操作方法
public class DBUtil {
private static String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
private static String user = "root";
private static String password = "123456";
public static PreparedStatement pstmt = null ;
public static Connection connection = null ;
public static ResultSet rs = null ;
//通用的:查询总数
public static int getTotalCount(String sql ) {//select count(*) from xx ;
int count = -1 ;
try {
pstmt = createPreParedStatement(sql, null) ;
rs = pstmt.executeQuery() ;//88
if(rs.next()) {
count= rs.getInt( 1 ) ;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}finally {
closeAll(rs, pstmt, connection);
}
return count ;
}
//通用的:当前页的数据集合 ,因此当前的数据 是强烈依赖于实体类,例如 显示当前页的学生, List<Student>
//因此需要将此方法 写入到dao层
// public static List<Student>
//通用的增删改
public static boolean executeUpdate(String sql,Object[] params) {//{"zs",1}
try {
//Object[] obs = { name,age ,...,x} ;
// String sql = "delete from xxx where Name = ? or id = ? " ;
// pstmt.setInt(1,sno );
//setXxx()方法的个数 依赖于 ?的个数, 而?的个数 又和 数组params的个数一致
//setXxx()方法的个数 ->数组params的个数一致
pstmt = createPreParedStatement(sql,params);
int count = pstmt.executeUpdate() ;
if(count>0)
return true ;
else
return false ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false ;
} catch (SQLException e) {
e.printStackTrace();
return false ;
}catch (Exception e) {
e.printStackTrace();
return false ;
}
finally {
closeAll(null,pstmt,connection);
}
}
//Statement
public static void closeAll(ResultSet rs,Statement stmt,Connection connection)
{
try {
if(rs!=null)rs.close();
if(pstmt!=null)pstmt.close();
if(connection!=null)connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver") ;
return DriverManager.getConnection( url,user,password ) ;
}
public static PreparedStatement createPreParedStatement(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 ResultSet executeQuery( String sql ,Object[] params) {//select xxx from xx where name=? or id=?
try {
// String sql = "select * from student" ;//select enmae ,job from xxxx where...id>3
pstmt = createPreParedStatement(sql,params);
rs = pstmt.executeQuery() ;
return rs ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null ;
} catch (SQLException e) {
e.printStackTrace();
return null ;
}catch (Exception e) {
e.printStackTrace();
return null ;
}
// finally {
// try {
// if(rs!=null)rs.close();
// if(pstmt!=null)pstmt.close();
// if(connection!=null)connection.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
}
}