首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

基于三层架构的分页实现

如果要显示10条数据,如图

图显示10条数据

试想,如果存入100条数据,则页面一定会被拉的很长,用户必须拉滚动条才能访问全部数据。

如果数据量更大,一千条、一万条、甚至几十万、几百万条数据呢?显然,将如此多的数据放在同一个页面中显示是不可取的。因此,我们就需要通过分页技术来减轻页面的负荷。

所谓分页,就是将原来在一个页面显示的数据,分到多个页面中显示,并且可以通过页码在多个页面之间切换。

分页的实现有多种方式,我们在此介绍最常用的一种:每次翻页的时候,只从数据库里查询出当前页所需要的数据。此种分页方式,需要依赖SQL语句,但不同数据库的SQL语句之间存在着差异。因此在编写分页时,我们需要对不同的数据库,写不同的SQL语句,本书采用的是Oracle数据库。下面就通过代码,来实际讲解一下分页。

本章的演示项目名为StudentManagerWithPage,是建立在之前的StudentManagerBy3TierAndInterface项目的基础上。

实现分页,需要提供5个属性(变量):

1数据总数:一共有多少条数据需要显示;可以通过”select count(1) from…”从数据库表中获取。

2页面大小:每页显示几条数据;可以由用户自己设置。

3总页数:总页数可以由“数据总数”和“页面大小”计算得出。例如,如果一共有80条数据(即“数据总数”为80),而每页只显示10条(即“页面大小”为10),则可以得到总页数=80/10=8(正好除尽,没有余数),共8页;如果一共有82条数据,每页仍然显示10条,则总页数=82/10(有余数)+1=9,共9页数据。因此,我们在求总页数之前,需要先判断是否有余数。综上,求总页数的公式:

总页数=(数据总数%页面大小==0)?(数据总数/页面大小):(数据总数/页面大小+1)

需要注意,因为“总页数”是由“数据总数”和“页面大小”计算而来的,所以不应该手动的为“总页数”赋值,即不存在“总页数”的setter方法。

4当前页的页码:指定需要显示第几页的数据可以由用户自己指定。

5实体类集合:如List students,用来保存当前页面中全部学生的信息。

为了便于维护,我们把这5个属性封装到一个Page类中,并提供相应的getter/setter方法,如下,

再在数据访问层,增加分页操作需要的两个方法:获取数据总数的方法,获取当前页面中全部学生的信息的集合的方法(例如获取List students集合的值)。而这两个方法都需要使用特定的SQL语句:

获取数据总数方法:使用“select count(*) from student”语句即可。

获取当前页面中全部学生的信息的集合:

我们需要知道当前页的第一条及最后一条数据的行号,然后使用“select * from student where编号>=第一条数据行号and编号

表每页显示的数据

可以发现,第n页需要显示的数据,就是第(n-1)*10+1条至第n*10条之间的数据,而其中的“10”就是“页面大小”。因此,第n页需要显示的数据范围如下:

第“(n-1)*页面大小+1”条 至 第 “n*页面大小”条

所以,查询当前页的全部学生信息的SQL为:

将上述SQL进行优化,可以写成如下形式,

以上,就是使用oracle时的分页SQL语句,可以发现此SQL语句需要“当前页的页码(currentPage)”和“页面大小(pageSize)”两个参数,而这两个参数需要通过三层逐步传递:用户通过JSP输入或指定currentPage和pageSizeà在JSP中,将二者附加在超链接或表单中,传入表示层后端代码Servlet中à在Servlet中,将二者传入SERVICE层方法的入参中à再在SERVICE层中,将二者传入DAO层方法的入参中à最后在DAO层中,将二者放入分页的SQL语句之中,并通过DBUtil执行最终的SQL语句,从而实现分页。具体如下(演示代码的顺序:数据库帮助类DBUtilàDAO层àSERVICE层àUI层):

为了实现分页,DBUtil需要从数据库查询数据总数(Page类中的属性totalCount),以及当前页面中全部学生信息的集合(Page类中的属性students)。因此需要在DBUtil中加入“查询数据总数”方法getTotalCount()和查询学生信息集合(结果集)的方法executeQuery();其中executeQuery()在之前的DBUtil中已经讲解过,这里不再赘述。

DBUtil.java

再在DAO层,加入“获取数据总数”方法,和“获取当前页面中全部学生信息的集合”方法:

IStudentDao.java接口

StudentDaoImpl.java实现类

然后在SERVICE层,加入“获取数据总数”方法,和“获取当前页面中全部学生信息的集合”方法

IStudentService.java接口

StudentServiceImpl.java实现类

不难发现,SERVICE层和DAO层,都需要currentPage(当前页)和pageSize(页面大小)两个参数。现在,我们就通过表示层来获取这两个参数:

先在表示层的后台代码(查询Servlet)中加入控制页码的程序,然后给Page类的各个属性赋值,最后再跳转到表示层的前台JSP中:

QueryAllStudentsServlet.java

阅读以上代码可知,currentPage(当前页)的值,是通过前台JSP传来的currentPage设置的;而pageSize(页面大小)的值,是通过硬编码的方式直接写成了3(读者也可以尝试将pageSize的值通过前台传来)。

因为程序是先执行QueryAllStudentsServlet,然后再跳转到显示页面index.jsp中,因此需要将QueryAllStudentsServlet设置为项目的默认启动程序,如下:

web.xml

最后,再在表示层的前台代码中,获取Servlet传来的Page类对象pages,通过pages获取到当前页的学生数据集合等信息,最后再通过用户的点击,来设置currentPage的值:

至此,就可以将分页SQL需要的两个参数“当前页的页码”及“页面大小”全部得到,也就完整的实现类分页功能。分页示例的完整代码在StudentManagerWithPage项目中,运行结果如图所示。

图分页显示

说明:

基于不同数据库的分页操作,唯一不同的就是SQL语句。除了oracle以外,其他常用数据库(如MySql、SqlServer)中的分页SQL语句如下:

MySql:

select * from表名limit当前页的页码*页面大小,页面大小;

SqlServer:

select top页面大小* from表名where id not in(select top (当前页的页码-1)*页面大小id from表名)

其中id表示“数据表的唯一标示符”

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180609A0VNBU00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券