使用servlet和c标签以及PageBean实现分页查询

分页查询

本次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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值