随笔-348  评论-598  文章-0  trackbacks-0

 

package com.jsecode.util.pagination;

import java.util.ArrayList;

import java.util.List;

import javax.faces.context.FacesContext;

import javax.faces.model.DataModel;

import com.gcoresoft.jsfdemo.bean.CarBeanDAO;

public class DataScrollerList extends BasePagedBackingBean
{

    CarBeanDAO dao 
= null;

    
public DataScrollerList()
    
{
        dao 
= new CarBeanDAO();
    }


    
public int getTotalCount()
    
{

        
int totalCount = 0;

        totalCount 
= dao.getTotalCount();

        
return totalCount;

    }


    
/**
     * 
     * 在DataScrollerList这个 Backing Bean中加一些东西,<br>
     * 
     * 调用业务逻辑,并将数据交给PagedListDataModel,来帮我们完成最后的分页工作。
     * 
     
*/


    
public DataPage getDataPage(int startRow, int pageSize)
    
{

        DataPage dataPage 
= dao.getDataPage(startRow, pageSize);

        
return dataPage;

    }


}

JSP页面:

    <f:view>
        
<h:form>
            
<rich:dataTable id="carList" width="483" rows="12" columnClasses="col"
                value
="#{scrollerList.dataModel}" var="car">
                
<f:facet name="header">
                    
<rich:columnGroup>
                        
<h:column>
                            
<h:outputText styleClass="headerText" value="Name" />
                        
</h:column>
                        
<h:column>
                            
<h:outputText styleClass="headerText" value="Decription" />
                        
</h:column>
                        
<h:column>
                            
<h:outputText styleClass="headerText" value="Base Price" />
                        
</h:column>
                        
<h:column>
                            
<h:outputText styleClass="headerText" value="Time" />
                        
</h:column>
                        
<h:column>
                            
<h:outputText styleClass="headerText" value="操作操作" />
                        
</h:column>                        
                    
</rich:columnGroup>
                
</f:facet>
    
                
<h:column>
                    
<h:outputText value="#{car.name}" />
                
</h:column>
                
<h:column>
                    
<h:outputText value="#{car.description}" />
                
</h:column>
                
<h:column>
                    
<h:outputText value="#{car.baseprice}" />
                
</h:column>
                
<h:column>
                    
<h:outputText value="#{car.timestamp}" />
                
</h:column>
                
<h:column>
                    
<h:commandLink action="#{user.delete}" value="删除" >
                        
<f:param name="id" value="#{car.id}"/>
                    
</h:commandLink>
                
</h:column>                
            
</rich:dataTable>
            
<rich:datascroller for="carList" id="dc1"
            style
="width:483px" page="#{user.scrollerPage}"/>                        
        
</h:form>
    
</f:view>
faces-config.xml:
 <managed-bean>
  
<managed-bean-name>scrollerList</managed-bean-name>
  
<managed-bean-class>com.jsecode.util.pagination.DataScrollerList</managed-bean-class>
  
<managed-bean-scope>session</managed-bean-scope>
 
</managed-bean> 
DataPage.java:
package com.jsecode.util.pagination;

import java.util.List;

public class DataPage
{

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


    
private int datasetSize;

    
private int startRow;

    
private List data;

    
/**
     * 
     * 
@param datasetSize
     *            数据集大小
     * 
@param startRow
     *            起始行
     * 
@param data
     *            数据list
     
*/

    
public DataPage(int datasetSize, int startRow, List data)
    
{

        
this.datasetSize = datasetSize;

        
this.startRow = startRow;

        
this.data = data;

    }


    
/**
     * 
     * 
@return
     
*/

    
public int getDatasetSize()
    
{

        
return datasetSize;

    }


    
public int getStartRow()
    
{

        
return startRow;

    }


    
/**
     * 
     * 
@return 已填充好的数据集
     
*/

    
public List getData()
    
{

        
return data;

    }


}

PagedListDataModel.java:
package com.jsecode.util.pagination;

import javax.faces.model.DataModel;

/**

 * 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.

 
*/


/**
 * 
 * 这个类里面的方法被dataTable调用顺序为:<br>
 * 
 * 1.构造函数public PagedListDataModel(int pageSize) <br>
 * 
 * 2.getRowCount()<br>
 * 
 * 3.setRowIndex()<br>
 * 
 * 4.public boolean isRowAvailable()<br>
 * 
 * 5.public Object getRowData()
 * 
 
*/


public abstract class PagedListDataModel extends DataModel
{

    
int pageSize;

    
int rowIndex;

    
private int rowCount = -1;

    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()
    
{

        
if ( rowCount < 0 ) {
            rowCount 
= fetchRowCount();
        }


        
return rowCount;

    }


    
/**
     * 
     * 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(String name)
    
{

        
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);

            rowCount 
= page.getDatasetSize();//

        }


        
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);

            rowCount 
= page.getDatasetSize();

            startRow 
= page.getStartRow();

        }
 else if ( rowIndex >= endRow ) // 向后取数据

            page 
= fetchPage(rowIndex, pageSize);

            rowCount 
= page.getDatasetSize();//

            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.
     * 
     
*/


    
public boolean isRowAvailable()
    
{

        DataPage page 
= getPage("isRowAvailable");

        
if ( page == null ) {

            
return false;

        }


        
int rowIndex = getRowIndex();

        
if ( rowIndex < 0 ) {

            
return false;

        }
 else if ( rowIndex >= page.getDatasetSize() ) {

            
return false;

        }
 else {

            
return true;

        }


    }


    
/** */

    
/**
     * 
     * Method which must be implemented in cooperation with the managed bean
     * 
     * class to fetch data on demand.
     * 
     
*/


    
public abstract DataPage fetchPage(int startRow, int pageSize);

    
public abstract int fetchRowCount();

}

BasePagedBackingBean:
package com.jsecode.util.pagination;

import javax.faces.model.DataModel;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public abstract class BasePagedBackingBean
{

    
protected abstract DataPage getDataPage(int startRow, int pageSize);

    
public abstract int getTotalCount();

    
private DataModel dataModel;

    
private int i = 0;

    
// 为什么getDataModel这个方法要调用两次?非常不解啊
    public DataModel getDataModel()
    
{

        
if ( dataModel == null ) {
            dataModel 
= new LocalDataModel(10);
        }


        
return dataModel;

    }


    
public Object getBean(String beanName)
    
{

        
return null;
    }


    
private class LocalDataModel extends PagedListDataModel
    
{

        
public LocalDataModel(int pageSize)
        
{

            
super(pageSize);

        }


        
public int fetchRowCount()
        
{

            
return getTotalCount();

        }


        
public DataPage fetchPage(int startRow, int pageSize)
        
{

            
// call enclosing managed bean method to fetch the data

            
return getDataPage(startRow, pageSize);

        }


    }


}

DataScrollerList.java:
package com.jsecode.util.pagination;

import java.util.ArrayList;

import java.util.List;

import javax.faces.context.FacesContext;

import javax.faces.model.DataModel;

import com.gcoresoft.jsfdemo.bean.CarBeanDAO;

public class DataScrollerList extends BasePagedBackingBean
{

    CarBeanDAO dao 
= null;

    
public DataScrollerList()
    
{
        dao 
= new CarBeanDAO();
    }


    
public int getTotalCount()
    
{

        
int totalCount = 0;

        totalCount 
= dao.getTotalCount();

        
return totalCount;

    }


    
/**
     * 
     * 在DataScrollerList这个 Backing Bean中加一些东西,<br>
     * 
     * 调用业务逻辑,并将数据交给PagedListDataModel,来帮我们完成最后的分页工作。
     * 
     
*/


    
public DataPage getDataPage(int startRow, int pageSize)
    
{

        DataPage dataPage 
= dao.getDataPage(startRow, pageSize);

        
return dataPage;

    }


}

每个DAO都实现了这个接口:
package com.gcoresoft.jsfdemo.bean;

import java.util.List;

import com.jsecode.util.pagination.DataPage;

/**
 * 
@author TiGERTiAN tigertian@gmail.com
 * 
@version  
 * Oct 29, 2008 9:46:55 AM
 
*/


public interface Pagination
{
    
public int getTotalCount();
    
public DataPage getDataPage(int startRow, int pageSize);
    
public List getPagedList(int startRow, int pageSize);
}

DAO中的相关代码:
    public DataPage getDataPage(int startRow, int pageSize)
    
{
        
// TODO Auto-generated method stub
        return new DataPage(getTotalCount(), startRow, getPagedList(startRow, pageSize));
    }


    
public int getTotalCount()
    
{
        Query q 
= EntityManagerHelper.createQuery("select count(*) from CarBean");
        System.out.println(
"row count = " + q.getSingleResult().toString());
        
return Integer.parseInt(q.getSingleResult().toString());
    }


    
public List getPagedList(int startRow, int pageSize)
    
{
           String sql 
= "from CarBean model order by model.id desc";

           Query query 
= EntityManagerHelper.createQuery(sql);

           query.setFirstResult(startRow);

           query.setMaxResults(pageSize);

           List list 
= query.getResultList();
           System.out.println(
"current row count = " + list.size());
           
return list;

    }




---------------------------------------------------------
专注移动开发

Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
posted on 2008-10-29 10:58 TiGERTiAN 阅读(2818) 评论(3)  编辑  收藏 所属分类: JavaJSF

评论:
# re: RichFaces中使用datatable和datascroller进行分页(使用数据库分页)(含源码)(JSF 1.2,RichFaces 3.2.1GA) 2008-12-12 20:31 | BioMed
Hi!

Can you post the user bean?
I'm interested in how you manage the scroller control.

Thanks you in advance!  回复  更多评论
  
# re: RichFaces中使用datatable和datascroller进行分页(使用数据库分页)(含源码)(JSF 1.2,RichFaces 3.2.1GA) 2008-12-12 23:16 | TiGERTiAN
@BioMed
Hi,you can reference this one http://www.blogjava.net/TiGERTiAN/archive/2008/11/04/238692.html, and if you have more questions about JSF pagnation, welcome to ask.  回复  更多评论
  
# re: RichFaces中使用datatable和datascroller进行分页(使用数据库分页)(含源码)(JSF 1.2,RichFaces 3.2.1GA) 2008-12-18 18:28 | BioMed
Many thanks i'll try it.  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: