0 项目来源与阅读建议
项目来源
http://how2j.cn/k/tmall-j2ee/tmall-j2ee-894/894.html?p=66748
注册的时候用这个链接,谢谢啦!
价格
92 * 0.8
阅读建议
- 本教程与站长的官方教程互为补充,并不是取而代之,也做不到取而代之。站长是以老师的身份告诉你怎么写,我是以课代表的身份告诉你,我是怎么学的。
- 本教程应当在你做完站长相对应部分的内容之后,再来看。也就是说,在看本教程之前,你应当对站长对应章节的内容有了一定的了解和基础,不然某些词语你可能听不懂。
- 我在How2j的ID名叫HuangTY,我喜欢分享大家存在的问题,所以也希望大家能够在评论区多多留言,共同进步。
1 分页概述
这一张主要讲解分页,分页在本项目中主要通过Page类与adminPage.jsp实现。
2 Page类
Page类:具有以下属性
1 查询记录从start开始,查询count条。[start,start+count),左闭右开。
请看sql语句——
String sql = "select * from Category order by id desc limit ?,? ";
相当于是按照id进行降序排序,然后取从start开始的count条。
2 计算总数,最后一页的首记录号为多少。
3 判断是否存在上一页,是否存在下一页。
关于2,3的例子,帮助理解:
这是2的例子:一共51个数据,每页5条。那么一共有11页,最后1页第1条标号为50.(limit ?,?的第一个?从0开始,所以是0到50)
这是3的例子:如果当前start为0,说明没有上一页。如果当前start为50说明没有下一页。
小结:
到这里,我们需要明确Page类能带给我们什么?
- 我可以设定起始页是多少,每页有多少个。
- 我们可以计算出一共需要分多少页面。
- 我们可以计算出最后一页的记录是从哪一条开始的。
- 我们可以判断当前页前面还有没有页,当前页后面还有没有页。
3 adminPage
这是个JSP。本质上我的详解教程是不准备再讲任何关于jsp的语法了,因为我时间不够了,只能专心把时间花在后端上,而JSP又是落后的技术。与Servlet不同的是,servlet技术本体已经被抛弃了,但是其本体依然作为“万恶之源”存在,一切的框架的核心基础都还是Servlet,因此掌握Servlet十分有必要。至于JSP嘛,我建议是直接跳过就算了。
那我们学后端,没有前端怎么办呢?
我们要非常清楚,我们需要给前端提供什么数据,前端通过这些数据能不能完成业务逻辑。至于具体的语法实现,可以不必强求。
3.1 翻页的业务基本需求
- 向前翻页。
1.1 判断存在前一页。
1.2 如果存在,向前翻。
1.3 怎么实现向前翻呢?前端发来的start -= count即可。大白话就是,向前翻count调记录。 - 向后翻页。
同上。 - 翻到最前一页。
3.1 判断是否存在前一页。
3.2 怎么判断是否存在最前一页呢?只要当前的start不等于0,那就必然存在最前页。因为start必然是count的整数倍,当start为0时,说明恰好在第一页。 - 翻到最后一页。
4.1怎么判断是否是最后一页呢?只要当前的start等于之前计算出的last,就说明是尾页,即没有下一页。 - 点击页码跳转到相应页面。
5.1 这边注意,页码是从1开始,start是从(1-0)*count开始的。
5.2 怎么跳转呢?DAO不是有list方法么?查询的时候可以传入参数,指定从start开始查,查count个。那每当点击一个页面,就把当前页码-1当做start传给DAO的list方法即可。
3.2 翻页的业务高阶需求
- 分页显示区间
试想这样一个业务场景,随着你的电商越做越大, 你的商品已经是百亿级别了。你像往常一下点入后台,结果——
分页从1显示到几千万页。
为了解决这样的问题,我们需要只显示当前页的前几个和后几个。代码通过如下实现
<c:if test="${status.count*page.count-page.start<=20 && status.count*page.count-page.start>=-10}">
通过判断在某一区间内才会设置相应标签和控件(前端我不太懂,就当是控件吧,类似按钮文本框之类的)。
4 整个的分页业务流程
浏览器正在显示adminPage画面(或当前JSP页面内包含adminPage页面),通过用户与浏览器的交互产生一次request请求,这个request请求夹带着start参数,走向filter。Filter发现是admin开头,便传给相对于的XxxServlet(图中未画出)。XxxServlet是继承自BaseBackServlet,执行service()方法时,先执行父类部分,成功利用start参数构造出了Page对象,但是因为count值为空,因此会catch到异常,但程序不会出问题,因为count默认为5。
举例说明
假如adminPage是包含在listCagegory页面的话,那么跳转前uri为admin_category_list。当用户产生交互后,产生一个request,uri变为admin_category_list?page.start=5。因此构建出的Page对象start=5,count=5.且因为uri为admin_category_list,因此在创建Page对象后,会调用list(start,count,page)方法,方法返回值为listCategory.jsp。所以显示器上会显示新的一个分页结果。
5 总结
这里有两个比较精妙的设计,第一个是BaseBackServlet类中的两个try…catch…
try {
start = Integer.parseInt(request.getParameter("page.start"));
} catch (Exception e) {
}
try {
count = Integer.parseInt(request.getParameter("page.count"));
} catch (Exception e) {
}
这段代码的作用是,有则改之,无则默认。如果有,那么就把start或count的值设置为传过来的数字,如果没有传相应的参数过来,那么就取默认值。
第二个地方时是设计模式方面的,将Page类和adminPage.jsp拿出来,实现了模块化和复用的效果。
6 下期预告
下期准备讲前端的业务逻辑。