数据库分页的实现

前言

  这是我的首篇技术文章,文章内容其实是一年前做项目的时候写的。今天拿出来共享一下,这篇文章适合初学者学习借用,也希望各位大神提出宝贵意见。

一、分页技术简介

  分页技术主要分三种:客户端分页、数据库分页、服务器端分页。

  客户端分页:客户端分页说的直白一点就是在前台进行分页。这种分页的方式减少了与数据库的交互次数,但主要不足之处在于它要先把所有的数据从数据库中读出来,然后再拿到前台进行分页,当数据量很大的时候,这种缺点暴露的就更加明显。

  数据库分页:这种分页方式刚好跟客户端分页相反,它是根据前台对pageSize的要求,按照pageSize的大小来查询数据库。当数据量很大时这种分页方式比较适用,只在页面上有查询需求时,后台才去查询数据库。这种分页方式加大了与数据库的交互次数

  服务器端分页:这种分页方式结合了前面两种分页方式。先将数据一次性从数据库中读取出来放到缓冲区,在客户端进行分页。

二、数据库分页技术实现

  1、com.***.data

    做分页之前,先将与分页相关的属性和方法封装成一个JavaBean,在上层将这些以对象的形式呈现给客户端。具体的实现代码如下:    

 1 package zhu.common.data;

 2 

 3 import java.util.List;

 4 

 5 public class Pager {

 6     private int totalRows;//记录总数

 7     private int pageSize = 5;//设置一页显示的记录数

 8     private int currentPage;//当前页码

 9     private int totalPages;//总页数

10 private int startRow;//当前页码开始记录数

11 private List elements;//记录列表

12 public Pager() {

13 }

14 //构造pager对象

15 public Pager(int _totalRows, int pageSize) {

16 this.pageSize=pageSize;

17 totalRows = _totalRows;

18 totalPages=totalRows/pageSize;

19 int mod=totalRows%pageSize;

20 if(mod>0){

21     totalPages++;//最后一页不足一页则总页数加1

22 }

23 currentPage = 1;//初始设置当前页为第一页

24     startRow = 0;//初始读取设置为0

25 }

26 

27 //点击首页按钮,执行这个方法

28 public void first() {

29     currentPage = 1;

30     startRow = 0;

31 }

32 //点击上一页按钮,执行这个方法

33 public void previous() {

34     if (currentPage == 1) {

35         return;

36     }

37     currentPage--;

38     startRow = (currentPage - 1) * pageSize;

39 }

40 //点击下一页按钮,执行这个方法

41 public void next() {

42     if (currentPage < totalPages) {

43         currentPage++;

44     }

45     startRow = (currentPage - 1) * pageSize;

46 }

47 //点击尾页按钮,执行这个方法

48 public void last() {

49     currentPage = totalPages;

50     startRow = (currentPage - 1) * pageSize;

51 }

52     

53 //做页面跳转时,执行这个方法

54 public void refresh(int _currentPage) {

55     currentPage = _currentPage;

56     if (currentPage > totalPages) {

57         last();//_currentPage超过了总页数,则跳转到最后一页

58     }

59     if(currentPage<1){

60         first();//_currentPage不足1,则跳转到首页

61     }

62     startRow = (currentPage - 1) * pageSize;//重新设置起始读取位置

63 }

64 /*此处略去35行setters和getters,但是在使用这个类时要加上*/

65 }
JavaBean

  2、com.***.utils

    将分页类设计成公用的util,不同的模块需要用到分页功能,都可以使用,但是前提是我们在applicationContext-dao.xml中配置了相应的bean

      <bean id="pagerManager" class="zhu.***.utils.PagerManagerImpl">

               <property name="hibernateTemplate">

                   <ref bean="hibernateTemplate" />

               </property>

      </bean>

    具体的实现代码如下:

    (1) interface IPagerManager

      分页工具对外的接口定义。具体的实现代码如下:

 1 package zhu.***.utils;

 2 

 3 import zhu.***.data.Pager;

 4 

 5 public interface IPagerManager {

 6 /*

 7  * 获取分页对象:

 8  * hsql:查询语句

 9  * currentPage:当前页

10  * pagerMethod:只有5种取值(first、previous、next、last、空值)(首页、上一页、下一页、尾页)

11  * 当pagerMethod为空值时,直接跳到currentPage所指定的页数

12  */

13     public Pager getPager(String hsql,Integer pageSize,String currentPage,String pagerMethod);

14 

15 }
IPagerManager

    

    (2) implement PagerManagerImpl

      

      分页工具对外的接口的实现。具体的实现代码如下:

 1 package zhu.***.utils;

 2 import java.util.ArrayList;

 3 import java.util.List;

 4 import org.hibernate.Query;

 5 import org.hibernate.Session;

 6 import org.springframework.orm.hibernate3.SessionFactoryUtils;

 7 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

 8 import zhu.***.data.Pager;

 9 

10 public class PagerManagerImpl extends HibernateDaoSupport implements IPagerManager {

11 /* 获取pager对象,用于传到页面

12 根据从页面上传过来的条件查询数据

13 currentPage主要用于指定页面跳转用,pagerMethod用于首页、前一页、后一页、尾页这四种请求的跳转

14 currentPage和pagerMethod不会同时不为空

15 */

16 public Pager getPager(String hsql,Integer pageSize, String currentPage, String pagerMethod) {

17 

18 int totalRows = 0;

19 List items = new ArrayList();

20 Pager pager = null;

21 Session session = SessionFactoryUtils.getSession(getSessionFactory(),true);

22 Query query = session.createQuery(hsql);

23 

24 totalRows = (query.list()).size(); //取得总计录数

25 //调用构造函数,初始化各种属性,包括currentPage=1和startRow=0

26 pager = new Pager(totalRows,pageSize);

27 //currentPage主要是做固定页面跳转用,从页面获取跳转页号赋给currentPage

28 //如果不为空,则根据从页面获取currentPage来刷新pager对象

29 if (currentPage != null) {

30 pager.refresh(Integer.parseInt(currentPage));

31 }

32 //pagerMethod有四种值即四种请求方式:首页,前一页,后一页,尾页。

33 if (pagerMethod != null) {

34     if (pagerMethod.equals("first")) {

35         pager.first();

36     } else if (pagerMethod.equals("previous")) {

37         pager.previous();

38     } else if (pagerMethod.equals("next")) {

39         pager.next();

40     } else if (pagerMethod.equals("last")) {

41         pager.last();

42     } 

43 }

44 //从当前页记录数开始

45 query.setFirstResult(pager.getStartRow());

46 //取出pageSize个记录

47 query.setMaxResults(pager.getPageSize());

48 items = query.list();//根据startRow和pageSize查询数据库

49 pager.setList(items);//将查询到数据列表赋值给pager对象的elements属性

50 

51 return pager;

52 }

53 }
PagerManagerImpl

  3、com.***.dao

    在模块中的DAO层使用分页工具,注意要先在该模块的dao.xml中进行配置相应的bean引用。

      <bean id="ModuleDAO" class="***">

               <property name="pagerManager">

                   <ref bean="pagerManager"/>

               </property>

      </bean>

      具体的实现代码如下:      

 1 package zhu.***.dao;

 2 import zhu.***.data.Pager;

 3     import zhu.***.utils.IPagerManager;

 4 

 5     public class ExampleDAOImpl {

 6     private IPagerManager pagerManager;

 7 /*

 8 exampleQueryCondition:查询条件

 9 ExampleTableName:数据表对应于持久化类类名

10 ExampleTablePropertyName:持久化类中的一个属性名

11 */

12     public Pager find(Integer exampleQueryCondition, Integer pageSize, String currentPage, String pageMethod) {

13 

14 String hsql = " from ExampleTableName where ExampleTablePropertyName = '" + exampleQueryCondition + "'";

15 return this.pagerManager.getPager(hsql, pageSize, currentPage,

16 pageMethod);

17 }

18 }
ExampleDAOImpl

 

你可能感兴趣的:(数据库)