JSF中分页的实现方式

在Web应用中如果遇到大数据集要处理时,分页显示往往是一个很好的解决方法。但是在JSF中没有直接实现分页显示的组件。但在Myfaces里的分页组件dataScroller如果直接显示的话,必须一次性的比所有要显示的记录都要检索出来,如果有10000条记录的话,一次性把这些记录全部检索出来的话,那么所消耗的内存是不敢想像的。所以我们应该做的是需要一页就检索一页。我最近在 http://wiki.apache.org/myfaces/WorkingWithLargeTables上页看到的一篇文章就实现了我所实现的功能。下面是我应用此方法所实现的一个分页显示:

 

 

 

首先得写一个用来包装一个页面数据的类:

 

 

 

package doorban.business;

 

import java.util.List;

 

public class DataPage {
 private int datasetSize; //数据集的记录总数

 

 private int startRow;    //从哪一条记录开始取数据

 

 private List data;       //一个页面的记录集

 

  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的类

 

 

 

package doorban.business;

 

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.

 

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

 

 * 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.
  */
 public boolean isRowAvailable() {
  DataPage page = getPage();
  if (page == null) {
   return false;
  }
  int rowIndex = getRowIndex();
  if (rowIndex < 0) {
   return false;
  } else if (rowIndex >= page.getDatasetSize()) {
   return false;
  } else {
   return true;
  }
 }

 

 /**
  * 这个方法在每一个业务里里必须要被实现

 

  * startRow 每页的第一条记录在数据集里的位置

 

  * pageSize 每页的记录数

 

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

 

}

 

接着就应该来写一个具体的业务类

 

package doorban.business;

 

import java.util.ArrayList;
import java.util.List;

 

import javax.faces.model.DataModel;

 

import doorban.dao.hb.TempCardActionHB;

 

public class TCB {

 

 private DataModel dataModel = null;

 

private int dataSetSize;

 

 // dataSetSize = actionHB.getTotal();

 

 TempCardActionHB actionHB = new TempCardActionHB();

 

 public DataModel getDataModel() {
  if (dataModel == null) {
   dataModel = new LocalDataModel(5);
  }

 

  return dataModel;
 }

 

 private class LocalDataModel extends PagedListDataModel {

 

  public LocalDataModel(int pageSize) {
   super(pageSize);
   try {
    dataSetSize = actionHB.getTotal();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }

 

  public DataPage fetchPage(int startRow, int pageSize) {

 

   TempCardActionHB actionHB = new TempCardActionHB();
   List list = new ArrayList();
   try {
    list = actionHB.getTempCards(startRow, pageSize);
   } catch (Exception e) {
    e.printStackTrace();
   }
   DataPage dataPage = null;
   try {
    dataPage = new DataPage(dataSetSize, startRow, list);
   } catch (Exception e) {
    e.printStackTrace();
   }
   return dataPage;
  }
 }
}

你可能感兴趣的:(DAO,apache,bean,Web,JSF)