`
yingjinsheng
  • 浏览: 25800 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
文章分类
社区版块
存档分类
最新评论

jsf自定义分页实现

阅读更多

     前面一篇直接使用了Myfaces中的两个Component完成了一个简单的分页,这里将会介绍一种On-demand loading的方法来进行分页,仅仅在需要数据的时候加载。

     先来说一些题外话,为了实现这种方式的分页,公司里大约5-6个人做了半个多月的工作,扩展了dataTable,修改了dataScrollor,以及各种其他的方法,但是都不是很优雅。在上个月底的时候,在MyfacesMail List中也针对这个问题展开了一系列的讨论,最后有人总结了讨论中提出的比较好的方法,提出了以下的分页方法,也是目前实现的最为优雅的方法,也就是不对dataTabledataScrollor做任何修改,仅仅通过扩展DataModel来实现分页。

     DataModel 是一个抽象类,用于封装各种类型的数据源和数据对象的访问,JSFdataTable中绑定的数据实际上被包装成了一个DataModel,以消除各种不同数据源和数据类型的复杂性,在前面一篇中我们访问数据库并拿到了一个List,交给dataTable,这时候,JSF会将这个List包装成 ListDataModel dataTable访问数据都是通过这个DataModel进行的,而不是直接使用List

     接下来我们要将需要的页的数据封装到一个DataPage中去,这个类表示了我们需要的一页的数据,里面包含有三个元素:datasetSizestartRow,和一个用于表示具体数据的ListdatasetSize表示了这个记录集的总条数,查询数据的时候,使用同样的条件取count即可,startRow表示该页的起始行在数据库中所有记录集中的位置。

/** */ /**
 * A simple class that represents a "page" of data out of a longer set, ie a
 * list of objects together with info to indicate the starting row and the full
 * size of the dataset. EJBs can return instances of this type when returning
 * subsets of available data.
 
*/

public   class  DataPage
{
    
private   int  datasetSize;
    
private   int  startRow;
    
private  List data;

    
/** */ /**
     * Create an object representing a sublist of a dataset.
     * 
     * 
@param  datasetSize
     *            is the total number of matching rows available.
     * 
     * 
@param  startRow
     *            is the index within the complete dataset of the first element
     *            in the data list.
     * 
     * 
@param  data
     *            is a list of consecutive objects from the dataset.
     
*/

    
public  DataPage( int  datasetSize,  int  startRow, List data)
    
{
        
this .datasetSize  =  datasetSize;
        
this .startRow  =  startRow;
        
this .data  =  data;
    }


    
/** */ /**
     * Return the number of items in the full dataset.
     
*/

    
public   int  getDatasetSize()
    
{
        
return  datasetSize;
    }


    
/** */ /**
     * Return the offset within the full dataset of the first element in the
     * list held by this object.
     
*/

    
public   int  getStartRow()
    
{
        
return  startRow;
    }


    
/** */ /**
     * Return the list of objects held by this object, which is a continuous
     * subset of the full dataset.
     
*/

    
public  List getData()
    
{
        
return  data;
    }

}

 

     接下来,我们要对DataModel进行封装,达到我们分页的要求。该DataModel仅仅持有了一页的数据DataPage,并在适当的时候加载数据,读取我们需要页的数据。

 

/** */ /**
 * A special type of JSF DataModel to allow a datatable and datascroller to page
 * through a large set of data without having to hold the entire set of data in
 * memory at once.
 * <p>
 * Any time a managed bean wants to avoid holding an entire dataset, the managed
 * bean should declare an inner class which extends this class and implements
 * the fetchData method. This method is called as needed when the table requires
 * data that isn't available in the current data page held by this object.
 * <p>
 * This does require the managed bean (and in general the business method that
 * the managed bean uses) to provide the data wrapped in a DataPage object that
 * provides info on the full size of the dataset.
 
*/

public   abstract   class  PagedListDataModel  extends  DataModel
{
    
int  pageSize;
    
int  rowIndex;
    DataPage page;

    
/** */ /**
     * Create a datamodel that pages through the data showing the specified
     * number of rows on each page.
     
*/

    
public  PagedListDataModel( int  pageSize)
    
{
        
super ();
        
this .pageSize  =  pageSize;
        
this .rowIndex  =   - 1 ;
        
this .page  =   null ;
    }


    
/** */ /**
     * Not used in this class; data is fetched via a callback to the fetchData
     * method rather than by explicitly assigning a list.
     
*/


    
public   void  setWrappedData(Object o)
    
{
        
if (o  instanceof  DataPage)
        
{
            
this .page  =  (DataPage) o;
        }

        
else
        
{
            
throw   new  UnsupportedOperationException( " setWrappedData " );
        }

    }


    
public   int  getRowIndex()
    
{
        
return  rowIndex;
    }


    
/** */ /**
     * Specify what the "current row" within the dataset is. Note that the
     * UIData component will repeatedly call this method followed by getRowData
     * to obtain the objects to render in the table.
     
*/


    
public   void  setRowIndex( int  index)
    
{
        rowIndex 
=  index;
    }


    
/** */ /**
     * Return the total number of rows of data available (not just the number of
     * rows in the current page!).
     
*/


    
public   int  getRowCount()
    
{
        
return  getPage().getDatasetSize();
    }


    
/** */ /**
     * Return a DataPage object; if one is not currently available then fetch
     * one. Note that this doesn't ensure that the datapage returned includes
     * the current rowIndex row; see getRowData.
     
*/

    
private  DataPage getPage()
    
{
        
if  (page  !=   null )
        
{
            
return  page;
        }


        
int  rowIndex  =  getRowIndex();
        
int  startRow  =  rowIndex;
        
if  (rowIndex  ==   - 1 )
        
{
            
//  even when no row is selected, we still need a page
            
//  object so that we know the amount of data available.
            startRow  =   0 ;
        }


        
//  invoke method on enclosing class
        page  =  fetchPage(startRow, pageSize);
        
return  page;
    }


    
/** */ /**
     * Return the object corresponding to the current rowIndex. If the DataPage
     * object currently cached doesn't include that index then fetchPage is
     * called to retrieve the appropriate page.
     
*/


    
public  Object getRowData()
    
{
        
if  (rowIndex  <   0 )
        
{
            
throw   new  IllegalArgumentException(
                    
" Invalid rowIndex for PagedListDataModel; not within page " );
        }


        
//  ensure page exists; if rowIndex is beyond dataset size, then
        
//  we should still get back a DataPage object with the dataset size
        
//  in it
         if  (page  ==   null )
        
{
            page 
=  fetchPage(rowIndex, pageSize);
        }


        
int  datasetSize  =  page.getDatasetSize();
        
int  startRow  =  page.getStartRow();
        
int  nRows  =  page.getData().size();
        
int  endRow  =  startRow  +  nRows;

        
if  (rowIndex  >=  datasetSize)
        
{
            
throw   new  IllegalArgumentException( " Invalid rowIndex " );
        }


        
if  (rowIndex  <  startRow)
        
{
            page 
=  fetchPage(rowIndex, pageSize);
            startRow 
=  page.getStartRow();
        }

        
else   if  (rowIndex  >=  endRow)
        
{
            page 
=  fetchPage(rowIndex, pageSize);
            startRow 
=  page.getStartRow();
        }

        
return  page.getData().get(rowIndex  -  startRow);
    }


    
public  Object getWrappedData()
    
{
        
return  page.getData();
    }


    
/** */ /**
     * Return true if the rowIndex value is currently set to a value that
     * matches some element in the dataset. Note that it may match a row that is
     * not in the currently cached DataPage; if so then when getRowData is
     * called the required DataPage will be fetched by calling fetchData.
     
*/


a
分享到:
评论

相关推荐

    JSF中自定义分页呈现器(Render)的实现和应用

    为了解决这些问题,本文提出了一种结合JSF自定义呈现器组件技术实现分页查询的方法。 #### 自定义分页呈现器的设计原理 自定义分页呈现器的核心思想在于实现JSF中的自定义渲染器(Renderer),该渲染器负责绘制...

    jsf分页 jsf分页 jsf分页

    下面我们将深入探讨JSF中的分页实现。 首先,我们需要理解JSF的核心组件和分页相关的API。JSF是一个MVC(模型-视图-控制器)框架,其中UIComponent和ManagedBean是关键组成部分。分页通常涉及到两个主要部分:前端...

    jsf自带分页

    你可以在自定义组件或者现有的JSF库(如PrimeFaces)中找到专门用于分页的组件,比如PrimeFaces的`p:dataTable`就内置了分页功能。 2. 后端处理: 在后端,你需要编写代码来处理数据的分页。这通常涉及到计算每页...

    JSF数据分页的简单例子(源码)

    6. **自定义分页**:JSF提供了一些内置的分页选项,但开发者也可以选择自定义分页样式和行为,比如更改页码按钮的外观,添加跳转到指定页的功能等。 在这个"JSF数据分页的简单例子"中,源码应该包含了以上提到的...

    利用自定义渲染器实现JSF数据库表分页显示

    ### 使用自定义渲染器实现JSF数据库表分页显示 #### 概述 在JavaServer Faces (JSF) 应用程序中处理大量的数据时,分页是一个非常实用且必要的功能。通过合理地分页展示数据,不仅可以提高用户体验,还可以减少...

    JSF分页组件2

    在JSF中,我们可以使用各种分页组件来实现这一功能。本文将深入探讨JSF分页组件2的相关知识点,包括其原理、使用方法和最佳实践。 ### 1. 分页组件的基本概念 分页组件允许用户以有限的数量逐页查看数据,而不是一...

    JSF分页组件

    创建自定义分页组件涉及以下几个步骤: - **设计组件**: 首先,你需要设计一个UI组件,包含必要的HTML元素和CSS样式,以实现分页导航的布局。 - **编写后台逻辑**: 编写Java代码处理分页操作,包括计算总页数、根据...

    jsf 分页

    本篇将深入探讨JSF中的分页实现。 首先,我们需要理解分页的基本概念。分页是将大量数据分为多个较小的部分,每次只加载一部分到页面上,用户可以通过导航按钮在不同页面之间切换。在JSF中,我们可以利用组件库如...

    JSF分页控件 ,支持大容量可查询分页

    在JSF中,分页通常通过自定义组件或利用现有的第三方库如PrimeFaces、RichFaces等实现。 "JSF分页控件" 可能是基于某个特定的JSF库,比如PrimeFaces中的`p:datascroller`或`p:paginator`,或者自定义的组件。这些...

    java自定义分页标签

    本主题将深入探讨如何在Java中实现自定义分页标签,以便更好地控制和展示数据。 首先,我们要理解什么是分页。分页是一种将大量数据分割成多个小部分,每次只加载一部分到页面上的技术。这有助于减少服务器负载,...

    JSF分页代码和学习文件1

    1. **j-jsf4comps**:这个文件可能包含了一些JSF自定义组件,自定义组件允许开发者扩展JSF的默认组件库,创建自己的UI组件,以满足特定项目需求。这些组件可以封装复杂的业务逻辑,提供更丰富的交互性。 2. **page*...

    struts和jsf分页

    Struts和JSF是两种广泛使用的Java Web框架,它们各自有着独特的特性和优点,而“分页”则是Web开发中的一个重要概念...在实际应用中,开发者可以根据项目的规模、性能要求以及团队的技术栈来选择最适合的分页实现方式。

    JSF 分页方案

    综上所述,“JSF分页方案”主要涉及创建自定义数据模型以实现分页逻辑,配合JSF视图组件来展示和处理分页请求,以及设计友好的用户界面和适当的缓存策略。通过这些步骤,开发者能够在JSF应用中高效地实现分页功能,...

    jsf_page.rar_ jsf_page_JSF_PAGE_java jsf_jsf glassfish_jsp page

    - 如果JSF提供的默认分页组件不能满足需求,开发者可以创建自定义组件,实现更复杂的功能,如动态加载、分页效果等。 7. 性能优化: - 分页处理不仅要考虑用户体验,还要考虑服务器性能。优化包括减少数据库查询...

    JSF学习代码

    5. **分页(Pagination)**:在**"JSF 分页学习代码"**标签下,可能包含了一个示例,展示如何在JSF应用中实现数据的分页显示,这通常涉及到对大量数据集的处理和展示策略。 6. **JSF与Spring、Hibernate集成**:在`...

    很方便的分页,主要用标签实现

    传统的分页实现方式一般包括以下步骤: 1. 用户点击页码或使用导航按钮。 2. 客户端发送请求到服务器,包含当前页码和每页条目数等信息。 3. 服务器根据请求参数查询数据库,返回对应页的数据。 4. 服务器响应数据,...

    JSF学习代码3

    在JSF中实现分页,通常涉及到自定义标签库(Taglib),例如`pager-taglib-2.0.war`可能就是这样一个自定义标签库,它提供了一组用于创建分页UI的自定义组件。通过这些组件,开发者可以轻松地在页面间导航,并控制...

    利用eXtremeComponents标签来实现分页实例

    最后,`xe:pager`提供了丰富的自定义属性,如`firstPageText`、`lastPageText`等,可以用来改变分页链接上的文本。同时,你可以通过`pageChange`事件来监听用户对分页操作的响应,进行进一步的业务处理。 总之,...

Global site tag (gtag.js) - Google Analytics