分页查询
本次demo使用一个List<Map>模拟jdbc查询出来的数据,使用c标签,servlet来实现一个学生的分页查询功能。该demo是maven项目。普通的ant项目,只需下载pom.xml中引入的两个jar包即可。
一、pom.xml
<dependencies>
<!-- 报错ClassNotFoundException: javax.servlet.jsp.jstl.core.LoopTag -->
<!-- 打开版本包确实没看到LoopTag类 -->
<!-- <dependency> -->
<!-- <groupId>javax.servlet.jsp.jstl</groupId> -->
<!-- <artifactId>jstl</artifactId> -->
<!-- <version>1.2</version> -->
<!-- </dependency> -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
二、web.xml
<servlet>
<servlet-name>pageServlet</servlet-name>
<servlet-class>com.ykq.servlet.StudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>pageServlet</servlet-name>
<url-pattern>/searchStudent</url-pattern>
</servlet-mapping>
<!-- 这样只需在页面上访问项目,即可访问到student.jsp -->
<!-- 同时需注意student.jsp在WEB-INF文件夹的外面,tomcat不允许直接访问WEN-INF下的资源 -->
<!-- 若是student.jsp在WEB-INF,则该设置无法直接访问到student.jsp -->
<welcome-file-list>
<welcome-file>/student.jsp</welcome-file>
</welcome-file-list>
三、Student类
package com.ykq.bean;
/**
* @author YKQ
* 学生类.
*/
public class Student {
private String id;
private String name;
private boolean gender;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
四、PageBean类(实现分页功能的实体类)
package com.ykq.bean;
/**
* @author YKQ
* page实体.
*/
public class PageBean {
/**
* 学生总数.
*/
private int sum;
/**
* 页面容量.
*/
private int pageSize;
/**
* 当前页.
*/
private int currentPage;
/**
* 是否有前一页.
*/
private boolean hasPreviousPage;
/**
* 是否有后一页.
*/
private boolean hasAfterPage;
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public boolean isHasPreviousPage() {
return hasPreviousPage;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public boolean isHasAfterPage() {
return hasAfterPage;
}
public void setHasAfterPage(boolean hasAfterPage) {
this.hasAfterPage = hasAfterPage;
}
}
五、student.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%-- 导入c标签 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<script type="text/javascript">
<%--查看第一页数据--%>
function queryFirstStudent(){
<%--设置当前页为0--%>
document.getElementById("currentPage").value=0;
submit();
}
<%--查看上一页数据--%>
function queryLastStudent(){
<%--获取当前页--%>
var currentPage = document.getElementById("currentPage").value;
<%-- 当前页数为空设置查询第一页--%>
if('' == currentPage || 'undefined' == currentPage
|| currentPage == null){
currentPage = 0;
<%-- 当前页数为第一页时,提示为首页--%>
} else if(currentPage == 0){
alert("当前已经是首页");
} else {
currentPage = currentPage - 1;
}
<%-- 设置当前页为计算后的值. --%>
document.getElementById("currentPage").value = currentPage;
submit();
}
<%--查看下一页数据 --%>
function queryNextStudent(){
var currentPage = document.getElementById("currentPage").value;
<%-- 当前页数为空设置查询第一页--%>
if('' == currentPage || 'undefined' == currentPage
|| currentPage == null){
currentPage = 0;
} else {
currentPage = currentPage + 1;
}
document.getElementById("currentPage").value = currentPage;
submit();
}
<%-- 查看最后一页数据 --%>
function queryEndStudent() {
// 因为当前不知道最后一页是第多少页数据,数据可能增加了,或是删除了,
// 所以传输特定值,在后台处理计算最后一页的数据
document.getElementById("currentPage").value = -10000;
submit();
}
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body onload="submit()" >
<form action="<%=basePath %>searchStudent">
<table>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
<c:forEach items="${stuList}" var="student" >
<tr>
<td>${student.id}</td>
<td>${student.name}</td>
<td>${student.gender}</td>
<td>${student.age}</td>
</tr>
</c:forEach>
</table>
<select id="pageSize" name="pageSize" >
<%--使用c:if标签来控制option被选中--%>
<option <c:if test="${page.pageSize != 15 && page.pageSize !=20}">
selected="selected"
</c:if>>10</option>
<option <c:if test="${page.pageSize == 15}">
selected="selected"
</c:if>>15</option>
<option <c:if test="${page.pageSize == 20}">
selected="selected"
</c:if>>20</option>
</select>
<%-- 使用hidden传递当前页数 --%>
<input type="hidden" id="currentPage" name="currentPage"
value="${page.currentPage}"/>
<input id="sum" name="sum" type="hidden" value="${page.sum}" />
<%--使用c:if动态显示<< < > >> --%>
<c:if test="${page.hasPreviousPage && page.currentPage != 0}">
<input type="submit" onclick="queryFirstStudent()" value="<<"/>
<input type="submit" onclick="queryLastStudent()" value="<"/>
</c:if>
<c:if test="${page.hasAfterPage}">
<input type="submit" onclick="queryNextStudent()" value=">"/>
<input type="submit" onclick="queryEndStudent()" value=">>"/>
</c:if>
<input type="submit" onclick="submit()" value="查询"/>
<div>总共:${page.sum}个学生, 当前第${page.currentPage+1}页</div>
</form>
</body>
</html>
六、servlet实现类
package com.ykq.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.ykq.bean.PageBean;
import com.ykq.bean.Student;
import com.ykq.service.StudentService;
import com.ykq.service.impl.StudentServiceImpl;
/**
* @author YKQ
* servlet.
*/
public class StudentServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PageBean pageBean = new PageBean();
// 获取当前页
String currentPageStr = req.getParameter("currentPage");
// 默认获取第一页的数据
if(currentPageStr == null || "".equals(currentPageStr)) {
currentPageStr = "0";
}
int currentPage = Integer.parseInt(currentPageStr);
pageBean.setCurrentPage(currentPage);
// 获取每页的容量
String pageSizeStr = req.getParameter("pageSize");
// 默认每页10个
if(pageSizeStr == null || "".equals(pageSizeStr)) {
pageSizeStr = "10";
}
int pageSize = Integer.parseInt(pageSizeStr);
pageBean.setPageSize(pageSize);
StudentService studentService = new StudentServiceImpl();
List<Student> stuList = studentService.queryStudents(pageBean);
req.setAttribute("stuList", stuList);
req.setAttribute("page", pageBean);
// 请求转发,将后台查询的数据结果保存在req中,在传递至页面
req.getRequestDispatcher("student.jsp").forward(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
}
七、service接口
package com.ykq.service;
import java.util.List;
import com.ykq.bean.PageBean;
import com.ykq.bean.Student;
/**
* @author YKQ
* 学生service
*/
public interface StudentService {
public List<Student> queryStudents(PageBean pageBean);
}
八、service实现类
package com.ykq.service.impl;
import java.util.List;
import com.ykq.bean.PageBean;
import com.ykq.bean.Student;
import com.ykq.dao.StudentDao;
import com.ykq.service.StudentService;
/**
* @author YKQ
* service实现类.
*/
public class StudentServiceImpl implements StudentService {
public List<Student> queryStudents(PageBean pageBean) {
StudentDao studentDao = new StudentDao();
return studentDao.queryStudents(pageBean);
}
}
九、dao层实现类
package com.ykq.dao;
import java.util.ArrayList;
import java.util.List;
import com.ykq.bean.PageBean;
import com.ykq.bean.Student;
/**
* @author YKQ
* 模拟dao层查询结果.
*/
public class StudentDao {
/**
* 查询学生dao.
* @return List<Student>
*/
public List<Student> queryStudents(PageBean pageBean){
List<Student> students = getStudentList();
// 设置总数。
pageBean.setSum(students.size());
if(students.size() <= 0) {
pageBean.setHasPreviousPage(false);
pageBean.setHasAfterPage(false);
pageBean.setCurrentPage(0);
return null;
} else {
int currentPage = pageBean.getCurrentPage();
int pageSize = pageBean.getPageSize();
// 先特殊处理查询最后一页数据
// 计算currentPage等于最后一页的下标
if(-10000 == currentPage) {
currentPage = students.size()/pageSize;
if(students.size()%pageSize == 0) {
currentPage--;
}
pageBean.setCurrentPage(currentPage);
pageBean.setHasAfterPage(false);
if(currentPage == 0) {
pageBean.setHasPreviousPage(false);
} else {
pageBean.setHasPreviousPage(true);
}
return students.subList(currentPage*pageSize,
students.size());
// 不是查询最后一页数据
} else {
// 判断是否有前页
if (currentPage == 0) {
pageBean.setHasPreviousPage(false);
} else {
pageBean.setHasPreviousPage(true);
}
// 处理下一页不存在(前端没判断是否存在下一页,判断了也没用,数据增加了,
/// 下一页也从前端不存在到后端的存在了)
// 以及前一页不存在(数据删除了)等查询情况
// 查询距离当前要查询的页的最近的那一页
while(currentPage*pageSize >= students.size()
&& currentPage > 0){
currentPage--;
}
// 截取数据
if((currentPage+1)*pageSize<students.size()) {
pageBean.setHasAfterPage(true);
return students.subList(currentPage*pageSize, (currentPage+1)*pageSize);
} else{
pageBean.setHasAfterPage(false);
return students.subList(currentPage*pageSize, students.size());
}
}
}
}
/**
* 模拟jdbc返回总的查询结果.
* @return List<Student>
*/
private List<Student> getStudentList() {
List<Student> stuList = new ArrayList<Student>();
Student student0 = new Student();
student0.setId("10000");
student0.setName("张**");
student0.setGender(true);
student0.setAge(18);
Student student1 = new Student();
student1.setId("10001");
student1.setName("李**");
student1.setGender(false);
student1.setAge(20);
Student student2 = new Student();
student2.setId("10002");
student2.setName("万**");
student2.setGender(false);
student2.setAge(20);
Student student3 = new Student();
student3.setId("10003");
student3.setName("徐**");
student3.setGender(false);
student3.setAge(20);
Student student4 = new Student();
student4.setId("10004");
student4.setName("许**");
student4.setGender(false);
student4.setAge(20);
Student student5 = new Student();
student5.setId("10005");
student5.setName("陈**");
student5.setGender(false);
student5.setAge(20);
Student student6 = new Student();
student6.setId("10006");
student6.setName("程**");
student6.setGender(false);
student6.setAge(20);
Student student7 = new Student();
student7.setId("10007");
student7.setName("涂**");
student7.setGender(false);
student7.setAge(20);
Student student8 = new Student();
student8.setId("10008");
student8.setName("胡**");
student8.setGender(false);
student8.setAge(20);
Student student9 = new Student();
student9.setId("10009");
student9.setName("万**");
student9.setGender(false);
student9.setAge(20);
Student student10 = new Student();
student10.setId("10010");
student10.setName("刘**");
student10.setGender(false);
student10.setAge(20);
Student student11 = new Student();
student11.setId("10011");
student11.setName("郭**");
student11.setGender(false);
student11.setAge(20);
Student student12 = new Student();
student12.setId("10012");
student12.setName("花**");
student12.setGender(false);
student12.setAge(20);
Student student13 = new Student();
student13.setId("10013");
student13.setName("华**");
student13.setGender(false);
student13.setAge(20);
Student student14 = new Student();
student14.setId("10014");
student14.setName("魃**");
student14.setGender(false);
student14.setAge(20);
Student student15 = new Student();
student15.setId("10015");
student15.setName("黄**");
student15.setGender(false);
student15.setAge(20);
stuList.add(student0);
stuList.add(student1);
stuList.add(student2);
stuList.add(student3);
stuList.add(student4);
stuList.add(student5);
stuList.add(student6);
stuList.add(student7);
stuList.add(student8);
stuList.add(student9);
stuList.add(student10);
stuList.add(student11);
stuList.add(student12);
stuList.add(student13);
stuList.add(student14);
stuList.add(student15);
return stuList;
}
}
扩展——jdbc的使用
将上面StudentDao中的 getStudentList()方法,替换成下面的内容
/**
* 返回总的查询结果.
* @return List<Student>
*/
private List<Student> getStudentList() {
List<Student> stuList = JdbcUtil.getStudentList("");
return stuList;
}
工具类
这里简单的实现一下jdbc查询功能,实际上jdbc的实现最好是要读取jdbc.properties配置文件
package com.ykq.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.ykq.bean.Student;
public class JdbcUtil {
/**
* 本应该配置在配置文件中,此处简单直接写死。
*/
// 高版本的没有加上serverTimezone会报错:The server time zone value '?й???????'
// is unrecognized or represents more than one time zone.
private static final String url = "jdbc:mysql://localhost:3306/pagestudent?serverTimezone=GMT";
private static final String name = "root";
private static final String password = "123456";
private static final String sql = "select id, name, gender, age from student";
// + " where name like '%'?'%'";
public static List<Student> getStudentList(String stuName){
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, name, password);
PreparedStatement ps = conn.prepareStatement(sql);
// 在jdbc中顺序是从1开始
//ps.setString(1, stuName);
ResultSet rs = ps.executeQuery();
String id = null;
String name = null;
int gender = -1;
int age = -1;
Student student = null;
List<Student> stuList = new ArrayList<Student>();
// 判断查询结果不等于空,不然直接rs.next可能报空指针异常。
if(rs != null) {
while(rs.next()) {
student = new Student();
id = rs.getString(1);
student.setId(id);
name = rs.getString(2);
student.setName(name);
gender = rs.getInt(3);
student.setGender(gender == 1?true:false);
age = rs.getInt(4);
student.setAge(age);
stuList.add(student);
}
}
return stuList;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}