1.在DAO层连接数据库是使用limit查询,传入index和pageSize参数

如我按页查询我的book信息,返回一个Book类型的List

public List<Book>getLimitBookList(int index,int pageSize){
		Connection conn=JDBCUtil.getConnection();
		List<Book> Books=new ArrayList<>();
		ResultSet rs=null;
		String sql="select * from book limit ? , ?";
		PreparedStatement ps=null;
		try {
			ps=conn.prepareStatement(sql);
			ps.setInt(1, index);
			ps.setInt(2, pageSize);
			rs=ps.executeQuery();
			while(rs.next()) {
				Books.add(new Book(rs.getInt("id"),rs.getString("name"), rs.getString("writer"),rs.getString("category")));
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			JDBCUtil.close(conn, ps, rs);
		}
		return Books;
	}

并要有一个获得总记录数的方法,此处不在赘述

2.建立一个page的实体bean

其中成员如下:

private int pageNumber;
	private int pageSize;
	private int index;
	private int totalRecord;
	private List<T> data;
	private String path;
pageNumber需要经过过滤,防止页面上的上一页和下一页造成首页末页溢出

public int getPageNumber() {
		
		//如果pageNumber<1,则返回1
		if(pageNumber < 1){
			return 1;
		}
		
		//如果当前页大于总页数,则返回总页数
		if(pageNumber > getTotalPage()){
			return getTotalPage();
		}
		
		return pageNumber;
	}
需要有计算总页数的方法

public int getTotalPage() {
		
		/**
		 * 在这来计算总页数
		 * 	
		 * 		总记录数                 每页的条数                   总页数
		 * 		  10           2           5
		 * 		   9           2           5
		 * 		   8 	       2           4
		 * 		   7           2           4
		 * 
		 * 	当可以整除时:
		 * 	totalRecord/pageSize
		 * 
		 * 	当有余数时:
		 *  totalRecord/pageSize+1
		 */
		
		if(getTotalRecord()%getPageSize()==0){
			return getTotalRecord()/getPageSize();
		}else{
			return getTotalRecord()/getPageSize()+1;
		}
	}
需要通过当前页码来计算index,即limit搜索中的起始位置

public int getIndex() {
		
		/**
		 *  在getIndex方法中来计算index值
		 *  
		 *  index       pageSize         pageNumber
		 *    0			   3				  1
		 *    3            3                  2
		 *    6            3                  3
		 *    index = (pageNumber-1)*pagesize
		 */
		
		return (getPageNumber() - 1) * getPageSize();
	}
其余通过编译器生成set/get方法即可

3.在service层中需要new一个dao对象,传入pageNo和pageSize获得结果对象集合,获得总记录数,并使用这些成员创建一个page对象,返回给上层

public class BookPageService {
	private searchBookDao searchBookDao=new searchBookDao();
	public Page<Book>getBookList(int pageNo,int pageSize){
		//1.查询表中所有数据数
		int totalRecord = searchBookDao.getTotalRecord();
		//2.创建page对象
		Page<Book>page=new Page<Book>(totalRecord,pageNo,pageSize);
		//3.查询分页数据并存储到page中
		List<Book>list=searchBookDao.getLimitBookList(page.getIndex(), page.getPageSize());
		page.setData(list);
		return page;
	}
	
	public Book getBookById(int id) {
		return searchBookDao.getBookById(id);		
	}

}

4.创建一个BaseServlet,实现对方法的反射,使得可以通过调用servlet并在url中传入方法名来调用相关方法

@WebServlet("/BaseServlet")
public class BaseServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    protected static int pageNo=1;
    protected static int pageSize=2;//自行设定
   
    public BaseServlet() {  
    }
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			pageNo=Integer.parseInt(request.getParameter("pageNo"));
		} catch (NumberFormatException e) {
			e.getMessage();
		}
		//获取用户传递的请求参数
		String methodName=request.getParameter("method");
		//通过方法名获取到方法的对象
		//获取当前类的Class对象
		Class cla=this.getClass();
		//获取cla的的方法(Method对象)
		//getDeclaredMethod需要两个参数,方法名和参数名
		//因为在java需要通过方法名和参数列表来确定一个方法		
		try {
			//获取方法对象
			Method method=cla.getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
			//设置方法权限
			method.setAccessible(true);
			//调用方法
			//invoke用于调用一个方法,第一个参数时要调用方法的对象,剩下是调用方法需要的参数
			method.invoke(this, request,response);
		} catch (Exception e) {
			e.getMessage();
		}	
	}


5.创建一个搜索用servlet,继承BaseServlet父类,在其中定义方法,对页面请求进行处理

public class BookPageService {
	private searchBookDao searchBookDao=new searchBookDao();
	public Page<Book>getBookList(int pageNo,int pageSize){
		//1.查询表中所有数据数
		int totalRecord = searchBookDao.getTotalRecord();
		//2.创建page对象
		Page<Book>page=new Page<Book>(totalRecord,pageNo,pageSize);
		//3.查询分页数据并存储到page中
		List<Book>list=searchBookDao.getLimitBookList(page.getIndex(), page.getPageSize());
		page.setData(list);
		return page;
	}
	
	public Book getBookById(int id) {
		return searchBookDao.getBookById(id);		
	}

}


此处使用了getPath(request)方法,由于页面url每次传入时在后面加一个&pageNo=...,第二次后就会在url后进行叠加,如127.0.0.1:8080/xxxx.yyyServlet?pageNo=1&pageNo=2&pageNo=3,这样无法使用,于是对url进行一个过滤

	public static String getPath(HttpServletRequest request) {
		String requestURI = request.getRequestURI();
		String queryString = request.getQueryString();
		String url=requestURI+"?"+queryString;
		if (url.contains("&pageNo")) {
			url = url.substring(0, url.indexOf("&pageNo"));
		}
		return url;
	}

至此,后端分页已全部完成,下面来完成前端的分页

1.页面向servlet发送的请求格式应为如下:

<a href="${pageContext.request.contextPath }/BookPageServlet?method=getBookList&pageNo=1">

我们刚刚定义了BaseServlet的反射,便需要在url中传入一个method的parameter,用以获取调用哪个函数,并传入初始页面号1

2.在显示页面获取的Book集合对象为${page.data }
3.在显示页面加入页码条的代码

为实现java的封装思想,我们选择在表单最后静态包含一个paging.jsp页面,在该页面中写入页码条的代码

	<%@ page language="java" contentType="text/html; charset=UTF-8"
	    pageEncoding="UTF-8"%>
	<div id="page_nav" align="center">
		<a href="${page.path }&pageNo=1">首页</a> 
		<a href="${page.path }&pageNo=${page.pageNumber-1}">上一页</a> 
		<c:choose>
			<c:when test="${page.totalPage <= 5}">
				<c:set var="begin" value="1"></c:set>
				<c:set var="end" value="${page.totalPage }"></c:set>
			</c:when>
			<c:when test="${page.pageNumber<=3 }">
				<c:set var="begin" value="1"></c:set>
				<c:set var="end" value="5"></c:set>
			</c:when>
			<c:otherwise>
				<c:set var="begin" value="${page.pageNumber-2 }"></c:set>
				<c:set var="end" value="${page.pageNumber+2 }"></c:set>
				<c:if test="${end >=page.totalPage}">
					<c:set var="begin" value="${page.totalPage-4 }"></c:set>
					<c:set var="end" value="${page.totalPage }"></c:set>			
				</c:if>
			</c:otherwise>
		</c:choose>
		
		
	  	<c:forEach begin="${begin }" end="${end}" var="num">
			<c:if test="${page.pageNumber==num }">[${num }]</c:if>
			<c:if test="${page.pageNumber!=num }">
				<a href="${page.path }&pageNo=${num}">${num }</a>
			</c:if>
			 
		</c:forEach>
		<a href="${page.path }&pageNo=${page.pageNumber+1}">下一页</a> 
		<a href="${page.path }&pageNo=${page.totalPage}">末页</a> 
		共${page.totalPage }页,${page.totalRecord }条记录,跳转至<input type="text" id="pageInput">页 
		<input type="button" value="确定" id="btn1"/>
		<script type="text/javascript">
			$("#btn1").click(function(){
				
				var value= $("#pageInput").val();
				window.location="${page.path}&pageNo="+value;
			});
		</script>
	</div>

页面需要导入taglib-standard-impl、taglib-standard-spec、jquery.min.js三个包

至此,我们手工添加的页码条可以说大功告成了

—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——

表单分页是一个搜索功能所必备的功能之一,十分的重要,倘若没有,数据量小尚可,数据量大那网页就爆炸了。我们以前的增删查改一直没有考虑这个问题,因为我们都是基于自己测试的渺小的数据上。课程设计的分页也是使用的easy-ui,填一下复制一下代码,从数据库搜索出count(*)就完事了,也不知道是什么原理,具体在哪里实现的也不知道。今日的分页功能我尚为模仿老师的方法,完全脱离老师的代码和视频,要写出来可能相当的费劲,仍需要多加练习,深化理解。不会自己写而只会模仿、只会填代码是不会进步的,这只会将自己局限为一个码农的角色,把自己的视野定格在眼前的一亩三分地中。狮子不是天生会捕猎的,也是通过不断的练习、模仿才成为一匹草原之王,倘若出生就把它关在笼子里喂食,它只会成为一只张嘴咀嚼的家猫。我们不能把今天的内容单单的当做一个工具包,“以后要用了直接导入就行”,没有什么资源是永恒存在的,而对知识的理解并化为己有是永恒的。对于技术,如今的我们不是一个创造者的角色,我们是学习者是模仿者,我们学习的目标就是将可以利用的资源,可以学习的只是,转化为自己的东西,不断扩充自己的知识库,追寻创造者的脚印,虽不能说是楷模,但也要成为他人的模仿对象。


鸡汤作为一篇文章的结尾也许是必要的,也许是鸡肋,学习技术也许并不需要这样在结尾鸡汤一下。但我们过去接受的语文教育将这样的思想种植在了我们的大脑中,这样写更符合大众的风格。我们不研究哲学,我们不研究普世观,我们也不研究教育,我们不必去探索世间真相,我们不必去格物致知,我们也不必去学习一个营销号是怎样写一篇文的,我们只学习技术,博客只为提醒自己,那便不必在意那么许多,让形式停留在形式上。



更多推荐

Java互联网架构学习之page分页