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

来源:互联网 发布:matlab 无约束最优化 编辑:程序博客网 时间:2024/05/18 18:15

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,则返回1if(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(*)就完事了,也不知道是什么原理,具体在哪里实现的也不知道。今日的分页功能我尚为模仿老师的方法,完全脱离老师的代码和视频,要写出来可能相当的费劲,仍需要多加练习,深化理解。不会自己写而只会模仿、只会填代码是不会进步的,这只会将自己局限为一个码农的角色,把自己的视野定格在眼前的一亩三分地中。狮子不是天生会捕猎的,也是通过不断的练习、模仿才成为一匹草原之王,倘若出生就把它关在笼子里喂食,它只会成为一只张嘴咀嚼的家猫。我们不能把今天的内容单单的当做一个工具包,“以后要用了直接导入就行”,没有什么资源是永恒存在的,而对知识的理解并化为己有是永恒的。对于技术,如今的我们不是一个创造者的角色,我们是学习者是模仿者,我们学习的目标就是将可以利用的资源,可以学习的只是,转化为自己的东西,不断扩充自己的知识库,追寻创造者的脚印,虽不能说是楷模,但也要成为他人的模仿对象。


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



原创粉丝点击