举例详解用Java实现web分页功能的方法

作者:treeroot 时间:2021-07-27 10:50:19 

分页问题是一个非常普遍的问题,开发者几乎都会遇到,这里不讨论具体如何分页,说明一下Web方式下分页的原理。首先是查询获得一个结果集(表现为查询数据库获得的结果),如果结果比较多我们一般都不会一下显示所有的数据,那么就会用分页的方式来显示某些数据(比如20条)。因为Http的无状态性,每一次提交都是当作一个新的请求来处理,即使是换页,上一次的结果对下一次是没有影响的。

这里总结三种实现分页的方式,不知道还有没有别的!
1.每次取查询结果的所有数据,然后根据页码显示指定的纪录。
2.根据页面只取一页数据,然后显示这一页,这里要构造sql语句。
3.取一定页数的数据,就是前面两种的折中。

这里还要注意的是这些数据是放在request还是session中,这里一一讨论

1.一般不会放在session中,因为会占用大量内存,所以要放在request里面。
优点:实现比较简单,查询速度比较快。
缺点:占用内存多一些,网络传输数据多。
对于数据量比较少的查询这种方法比较合适。这里有人把数据放在session中,这样换页的时候就不用重新查询,但是这样是极其不好的,强烈建议不要这样使用。

2.肯定不会放在session中,因为放在session中没有意义。
优点:占用内存少。
缺点:比较麻烦,必须先获得查询结果的总数,因为要知道有多少纪录才知道有多少页。另外要构造分页查询语句,对于不同的数据库是不一样的。

3.这种情况是肯定放在session中了,要不然 * 吗取好几页呀,这样的实现是为了减少数据库查询的次数,比如我保存第1到10的纪录,那么换页的时候如果在1到10之间就可以直接从session获取。如果换到11页,我可以重新设置缓存11到
20页的数据(或者5到15页的数据),这样的话换10次才需要一次数据库查询操作。
优点:占用内存相对不多,提高平均查询速度。
缺点:实现起来更加复杂,可能存在脏数据,需要自己定义一个缓存集合。如果查询的数据量比较大,可以考虑采用这样方式。

下面的设计每次只获取一页数据,每次都要重新设置查询总数,具体如何获得自己实现,这是一个比较通用的分页实现。

这里设计一个接口:


package treeroot.util;
import java.util.List;
/**
* 该接口用来实现分页功能,注意这里没有提供修改的功能。
* @author treerot
* @version 1.0
* @since 2004-9-30
*/
public interface Pageable
{
/**
* 获得数据结果
* @return
*/
public List getResult();
/**
* 获得查询总数
* @return
*/
public int getCount();
/**
* 获得每页纪录数
* @return
*/
public int getPageSize();
/**
* 获得当前页编号
* @return
*/
public int getCurrentPage();
/**
* 获得总页数
* @return
*/
public int getPages();
/**
* 每页默认显示纪录数
*/
public final static int DEFAULT_PAGESIZE=20;

}

这个接口非常简单,就是包括一个结果列表和一些分页的必要信息,这里注意几点:
1.这个接口的实现表示的是某一次查询的某一页数据,和上次查询无关
2.这个接口的实现应该是只读的,也就是说不可以修改的。
3.getPages()方法是冗余的,但是这里仍然提供这个方法。

下面给出一个抽象实现:


package treeroot.util;
import java.util.List;
/**
* @author treerot
* @version 1.0
* @since 2004-9-30
*/
public abstract class AbstractPage implements Pageable
{
private int currentPage;
private int pageSize;
private int pages;

protected int count;
protected List result;

/**
* 指定当前页
* @param currentPage
* @throws PageException
*/
public AbstractPage(int currentPage){
this(currentPage,Pageable.DEFAULT_PAGESIZE);
}

/**
* 指定当前页和页大小
* @param currentPage
* @param pageSize
* @throws PageException
*/
public AbstractPage(int currentPage,int pageSize) {
this.currentPage=currentPage;
this.pageSize=pageSize;
}

protected void checkPage(int currentPage) throws PageException{
if((currentPage<1)||(currentPage>this.getPages()))
throw new PageException("页超出范围:总页数为"+this.getPages()+",当前页为"+currentPage);
}
/**
* 这个方法被子类重写用来初始化,也就是计算count值和result结果,在子类 的构造函数中调用。
*/
abstract protected void init() throws PageException;

public List getResult()
{
return result;
}

public int getCount()
{
return count;
}

public int getPageSize()
{
return pageSize;
}

public int getCurrentPage()
{
return currentPage;
}

public int getPages()
{
if(pages==0) this.pages=(count+pageSize-1)/pageSize;
return pages;
}
}

这个抽象类实现了接口中的所有方法,但是定义了一个抽象方法init(),在子类中必须实现这个方法。上面的一个接口和一个抽象类看起来比较简单,你可能会觉得好像什么都没有做,实现上确实没有做什么,但是却可以给开发带来很大的帮助。我们可以根据自己的需要要继承这个抽象类,而数据可以通过各种方式获得,比如直接通过一个List获得,或者通过JDBC,Hibernate等等,不过我们都需要把结果封装到一个List里面,通过Hibernate就显得特别方便了。

PageException是自定义的一个异常


package treeroot.util
/**
* @author treeroot
* @version 1.0
* @since 2004-9-30
*/
public class PageException extends Exception
{
public PageException(){
super();
}
public PageException(String message){
super(message);
}
}
标签:Java,分页
0
投稿

猜你喜欢

  • 使用Spring的拦截器监测每个Controller或方法的执行时长

    2021-12-19 16:36:01
  • Java面试题冲刺第二十二天-- Nginx

    2023-11-16 13:43:48
  • JAVA的反射机制你了解多少

    2023-11-29 16:46:38
  • Java 数据结构之删除链表中重复的结点

    2023-11-28 15:36:22
  • Android基础之使用Fragment控制切换多个页面

    2023-07-11 00:08:37
  • Android编程之消息机制实例分析

    2023-07-28 07:24:38
  • mybatis in foreach 双层嵌套问题

    2023-11-24 12:55:47
  • Java中的回调

    2023-11-16 01:55:58
  • 【java 多线程】守护线程与非守护线程的详解

    2023-11-29 01:35:29
  • IDEA(jetbrain通用)使用教程图解

    2023-04-15 04:05:49
  • Java设计通用的返回数据格式过程讲解

    2023-11-09 00:16:40
  • java中javaBean与Bean的深入理解

    2021-11-27 13:19:11
  • 利用java实现二叉搜索树

    2023-10-25 13:25:07
  • 浅析SpringBoot2底层注解@Conditional@ImportResource

    2023-08-01 23:35:51
  • SpringBoot如何使用RateLimiter通过AOP方式进行限流

    2023-09-16 18:18:44
  • SpringBoot核心@SpringBootApplication使用介绍

    2023-11-25 08:33:59
  • Java中ShardingSphere分库分表实战

    2023-11-24 09:20:37
  • C语言实现贪吃蛇游戏演示

    2023-07-03 14:16:43
  • springboot schedule 解决定时任务不执行的问题

    2021-05-30 05:00:38
  • java 发送http和https请求的实例

    2023-11-29 12:46:52
  • asp之家 软件编程 m.aspxhome.com