文档章节

displayTags大数据量分页导航

lgscofield
 lgscofield
发布于 2015/06/26 13:58
字数 1483
阅读 4
收藏 0
点赞 0
评论 0

 

李楠注:
    这个内容我还没有测试过,打算以后分别用mysql,mssql,oracle10g测试一下,
数据量分别为1万,2万,10万,100万。这里先把此文档保存下来。
    关注这个内容,主要是这个功能要经常使用,并且,每个框架的实现都不相同(比如hibernate,ibatis)。
这次,是因为我在分析ibatis的框架,而听说ibatis实现的PaginatedList接口在数据量不超过2万的时候,
可以使用,但遇到大数据量的时候会有问题。据说在一个30万行的表里翻页,
一次select用了363.031second。如果真是这样的话,只好自己实现这个接口了。
    以下,是文章的内容:
----------------------------------------------

由于displayTag只处理数据的显示,传递给他多少数据,它会根据数据的记录数及其每页显示多少计算出需要的页数,但是在处理大数据量集合的时候,会遇到问题,就是将所有的数据传递给displayTag表格显示标签变得不现实也没有必要,如何既能够用到dispalyTag强大的显示功能,用能够很好的处理大数据量的
显示和分页功能呢?


当我遇到这个问题的时候,感到无从下手,因为我当时并不是很熟悉displaytag,更不要提它的深层次的处理机制问题了,嘿嘿!于是我就开始在群里请教高人,未果,无奈之余我只有借助网络,哈,我不停的变换关键词进行搜索,结果发现不止是我一个人遇到此问题啊,那是千千万万啊(一点都不夸张)!在那些五花八门的答案中我开始筛选,实验。。。

最终,根据displayTag官方文档的推荐和网友们的建议,我做开始了解决这个问题的尝试(虽然之前我遇到这个问题的时候,就先请教了我的一个同事,但他给我的建议我感觉太麻烦了,改动比较大,于是就下决心一定自己解决这个问题啦!)

首先我了解到displaytag1.0实在是太傻了,每次分页还需要将所有数据一次载入,效率低到无法忍受:)而displaytag1.1就不同了,1.1版最大的改进可以说是终于支持了大家期待以久的分次加载功能了,想显示多少数据就载入多少数据.1.1版本支持两种方式的分页,第一种是实现其org.displaytag.pagination.PaginatedList 接口,第二种是在页面和后台同时做修改来实现分页功能.在网上关于第二种分页的使用方法介绍的非常多,而且官方文档上面写的也比较详细,所以在这里我主要介绍自己是如何使用第一种方式进行分页的,且这种方式也是官方推荐分页方式:

首先写一个org.displaytag.pagination.PaginatedList 接口的实现类:
//package com.greatroad.webapp.paging;

import java.util.List;

import org.displaytag.pagination.PaginatedList;
import org.displaytag.properties.SortOrderEnum;

/**
* PaginatedListImpl
* User: zhangyd
* Date: 2007-10-20
* Time: 20:35:18
*
* totalNum 所有条目数目
* currentPage 当前所在页号
* objectsPerPage 每页显示条数
* list 此页所需要显示的数据
*/
public class PaginatedListHelper implements PaginatedList{
      private List list;
      private int pageNumber = 1;
      private int objectsPerPage = 20;
      private int fullListSize = 0;
      private String sortCriterion;
      private SortOrderEnum sortDirection;
      private String searchId;

      public List getList() {
          return list;
      }

      public void setList(List list) {
          this.list = list;
      }

      public int getPageNumber() {
          return pageNumber;
      }

      public void setPageNumber(int pageNumber) {
          this.pageNumber = pageNumber;
      }

      public int getObjectsPerPage() {
          return objectsPerPage;
      }

      public void setObjectsPerPage(int objectsPerPage) {
          this.objectsPerPage = objectsPerPage;
      }

      public int getFullListSize() {
          return fullListSize;
      }

      public void setFullListSize(int fullListSize) {
          this.fullListSize = fullListSize;
      }

      public String getSortCriterion() {
          return sortCriterion;
      }

      public void setSortCriterion(String sortCriterion) {
          this.sortCriterion = sortCriterion;
      }

      public SortOrderEnum getSortDirection() {
          return sortDirection;
      }

      public void setSortDirection(SortOrderEnum sortDirection) {
          this.sortDirection = sortDirection;
      }

      public String getSearchId() {
          return searchId;
      }

      public void setSearchId(String searchId) {
          this.searchId = searchId;
      }

}
然后在使用的时候只需要创建此类的一个实例,且将所需要的参数通过set方法赋值进去就可以了,比如我在XXXController.java中是这样实现的(注意加粗的部分):

package com.greatroad.webapp.action;

import java.text.SimpleDateFormat;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.displaytag.pagination.PaginatedList;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.greatroad.Constants;
import com.greatroad.model.Station;
import com.greatroad.service.CardhistorydataManager;

import com.greatroad.service.StationManager;
import com.greatroad.webapp.paging.PaginatedListHelper;

public class CardhistorydataController implements Controller {
private final Log log = LogFactory.getLog(CardhistorydataController.class);

private CardhistorydataManager cardhistorydataManager = null;

public void setCardhistorydataManager(
     CardhistorydataManager cardhistorydataManager) {
    this.cardhistorydataManager = cardhistorydataManager;
}

private StationManager stationManager = null;

public void setStationManager(StationManager stationManager) {
    this.stationManager = stationManager;
}

public ModelAndView handleRequest(HttpServletRequest request,
                                        HttpServletResponse response)
      throws Exception {
          if (log.isDebugEnabled()) {
              log.debug("entering 'handleRequest' method...");
          }

          Object[] o = new Object[4];
          String personId = request.getParameter("person");
          String d1 = request.getParameter("starttime");
          String d2 = request.getParameter("endtime");
       
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
       
          if(personId!=null && personId.length()>0)
           o[0] = personId;
          if(d1!=null && d1.length()>0)
           o[1] = sdf.parse(d1);
          if(d2!=null && d2.length()>0)
           o[2] = sdf.parse(d2);
// ///////////////////////////////////////////////////////
          Station station = new Station();
          String stationId = request.getParameter("stationname");
          if(stationId!=null && stationId.length()>0){
           station = stationManager.getStation(stationId);
           o[3] = stationId;
           request.setAttribute("Stationid", stationId);
          }
           List stationList = stationManager.getStations(null);
           if(stationList != null && stationList.size()>0){
            request.setAttribute("stationlist", stationList);
           }
// /////////////////////////////////////////////////////////////////////////////
        /*
      * 其中request中的page参数为displaytag中的默认当前页数,当然也可以使用*TableTagParameters.SORT_AMOUNT_PAGE来表示当前页数
      */
        int pageSize;
        if (request.getParameter("pageSize") != null
          && !"".equals(request.getParameter("pageSize"))) {
         pageSize = Integer.parseInt(request.getParameter("pageSize"));
        } else {
         pageSize = 15;
        }

        int page = 1;
        if (request.getParameter("page") != null
          && !"".equals(request.getParameter("page"))) {
         page = Integer.parseInt(request.getParameter("page"));
        } else {
         page = 1;
        }

        int fromIndex = (page - 1) * pageSize;
//      int toIndex = fromIndex + pageSize;
        int toIndex = pageSize;
        // 获得每次查询的总记录数
        int ListSize = cardhistorydataManager.countListSize(o);//DAO中实现

        // 此页要显示的list数据
        List cardhistorydatas = null;

        if (ListSize > 0) {
         cardhistorydatas = cardhistorydataManager.getCardhistorydatas(o, fromIndex, toIndex);//DAO中实现
        } else {
         cardhistorydatas = null;
        }
        PaginatedList paginaredList = new PaginatedListHelper();
        ((PaginatedListHelper) paginaredList).setPageNumber(page);
        if (cardhistorydatas != null && ListSize != 0) {
         // System.out.println("getFullListSize: " + ListSize);
         // 总共有多少数据,他会根据所有数目和每页数目自动统计页数
         ((PaginatedListHelper) paginaredList).setFullListSize(ListSize);
         ((PaginatedListHelper) paginaredList).setObjectsPerPage(pageSize);
         ((PaginatedListHelper) paginaredList).setList(cardhistorydatas);
        } else {
         ((PaginatedListHelper) paginaredList).setFullListSize(0);
         ((PaginatedListHelper) paginaredList).setList(null);
        }
        // 如果你只设定这几个参数,那么其余的参数将会默认为你实现类中所赋的初值
        // 最后,你还需要将这个实例放入到request或session中去,好让displaytag知道这个是外部分页
//        request.setAttribute("cardhistorydataList", paginaredList);
////////////////////////////////////////////////////////////////////////////////

          return new ModelAndView("cardhistorydataList", Constants.CARDHISTORYDATA_LIST, paginaredList);
      }
}
当然还有相关的一些地方需要改动,如果你能做的这一步,其余的那些已经不是问题了^!^另外再强调一点:页面无需任何改动哦!

参考文献:http://displaytag.sourceforge.net/11/

本文转载自:http://lgscofield.iteye.com/blog/1678980

共有 人打赏支持
lgscofield

lgscofield

粉丝 20
博文 105
码字总数 63036
作品 0
南京
架构师
Table Storage对分页的支持

公告:本博客为微软云计算中文博客的镜像博客。部分文章因为博客兼容性问题,会影响阅读体验。如遇此情况,请访问原博客。 大家可能知道WCF Data Services最新版提供了server paging的功能,...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

简书的滑动悬停效果

2017-11-16 171045.gif 最近,浏览简书的时候,发现简书iOS客户端的个人主页,有这种滑动悬停的效果,自己也想动手实现下。下面是我的实现效果: 2.gif 3.gif 整个代码实现过程不复杂,复杂的...

Jesse1949 ⋅ 2017/11/16 ⋅ 0

mongo分页查询方式

闲下来,想了下准备总结下最近在mongo查询上所遇到的一些问题,我在这里罗列一下。 1.mongo使用shell的find查询: 查询long型字段时,需要在查询条件里使用NumberLong("xxxx")包裹起来,这样...

孙超飞 ⋅ 01/29 ⋅ 0

为什么有那么多人进行大数据培训?看完这些你就懂了

近几年,大数据这个词突然变得很火,国务院和其他国家的政府报告中多次提及,大数据无疑成为当今互联网世界中的新宠儿。而这之前,国内的所有高校中都没有设立大数据相关的课程,这也是为什么...

加米谷大数据 ⋅ 05/08 ⋅ 0

收集自网络的wordpress 分页导航的代码教程(全网最全版)

wordpress 分页导航是用来切换文章的一个功能,添加了 wordpress 分页导航后,用户即可自由到达指定的页面数浏览分类文章,而这样的一个很简单功能却有很多朋友在用插件:WP-PageNavi,插件的...

Rhymo-Wu ⋅ 前天 ⋅ 0

今日数据行业日报(2017年8月28日)

【投资经济】 BCG:2017年全球财富报告 BCG:2017年全球财富报告 | 互联网数据中心-199IT | 中文互联网数据研究资讯中心-199IT 普华永道:2017年上半年中国企业并购市场报告 普华永道:2017年...

DingLi ⋅ 2017/08/28 ⋅ 0

Fixwin电子窗体——基本信息模板

通过Fixwin电子窗体,设计几种常用的功能模块模版,在开发实际的项目时,采用模板创建相应模块能够节省工作量,并且通过模板建立的系统界面一致性也比较好。 以下是几种基本信息类的模板 模板...

彭博 ⋅ 2012/03/09 ⋅ 0

Elasticsearch——分页查询From&Size VS scroll

Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回。那么,如果要实现分页查询该怎么办呢? 更多内容参考Elasticsearch资料汇总 按照一般的查询流程来...

xiaomin0322 ⋅ 06/13 ⋅ 0

帝国cms采集图文教程(中)

上一讲我们介绍了帝国cms采集基本流程,那么我们这一讲介绍帝国cms如何采集内容分页。不少的同学在采集过程中,列表页和内容页都能可以很好地设定正则,但往往失败在内容分页正则上,主要是对...

国外网站大全 ⋅ 2012/03/12 ⋅ 0

jQuery 分页导航插件--Pagination2

Pagination 目前是基于 jQuery 的一个功能完善,简单易用 JavaScript 分页控件。它的目标单纯,给它配置一个totalPage 参数,它就给你生成一个简洁的分页导航。Pagination不会和关联的数据直...

前端巨浪 ⋅ 2016/12/29 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 14分钟前 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部