本文转自http://wiki.apache.org/myfaces/WorkingWithLargeTables,由于该文最后一部分没有jsp代码部分,所有又加上了一些jsp代码。
Components t:dataModel and t:dataScroller work together nicely to allow a user to "page" through a set of a few dozen to a few hundred records. However the implementation does assume that the entire set of available records are in memory and wrapped up inside a ListDataModel or ArrayDataModel.
When the available dataset is quite large, and the application can have many users, this can lead to memory usage problems.
This page contains discussions on how to handle this scenario.
On-demand loading
A custom DataModel can be used to allow data to be loaded "on demand".
First, a class needs to be defined which your "business methods" (eg EJBs) can use to pass "pages" of data back to the UI. This class needs to be defined in your project, as the "business" level shouldn't be extending MyFaces classes:
- package example;
-
- import java.util.List;
-
-
-
-
-
-
-
- public class DataPage<t></t> {
-
- private int datasetSize;
- private int startRow;
- private List<t></t> data;
-
-
-
-
-
-
-
-
-
-
-
-
-
- public DataPage(int datasetSize, int startRow, List<t></t> data) {
- this.datasetSize = datasetSize;
- this.startRow = startRow;
- this.data = data;
- }
-
-
-
-
- public int getDatasetSize() {
- return datasetSize;
- }
-
-
-
-
-
- public int getStartRow() {
- return startRow;
- }
-
-
-
-
-
- public List<t></t> getData() {
- return data;
- }
- }
Now a custom DataModel can use this DataPage stuff. Again, it is recommended that you copy this code into your project and change the package name appropriately. This class can't go in the MyFaces libraries as it depends on DataPage, and as noted above, DataPage is accessed by your business level code so it really can't be in the MyFaces libs:
Finally, the managed bean needs to provide a simple inner class that provides the fetchPage implementation:
java 代码
- public SomeManagedBean {
- ....
-
-
- private DataPage<somerowobject></somerowobject> getDataPage(int startRow, int pageSize) {
-
- }
-
- public DataModel getDataModel() {
- if (dataModel == null) {
- dataModel = new LocalDataModel(getRowsPerPage());
- }
-
- return dataModel;
- }
-
- private class LocalDataModel extends PagedListDataModel {
- public LocalDataModel(int pageSize) {
- super(pageSize);
- }
-
- public DataPage<somerowobject></somerowobject> fetchPage(int startRow, int pageSize) {
-
- return getDataPage(startRow, pageSize);
- }
- }
The jsp pages should be like this:
-
- public class PagedTableListBean {
-
- private DataModel pagedDataModel;
-
- private TableListBean listBean;
-
-
-
-
- public PagedTableListBean() {
-
- }
-
-
-
-
- public DataModel getItemList() {
- if (pagedDataModel == null) {
- pagedDataModel = new LocalDataModel(15);
- }
-
- return pagedDataModel;
- }
-
-
-
-
- public DataModel getPagedDataModel() {
- return pagedDataModel;
- }
-
-
-
-
-
- public void setPagedDataModel(DataModel pagedDataModel) {
- this.pagedDataModel = pagedDataModel;
- }
-
-
-
-
- public TableListBean getListBean() {
- return listBean;
- }
-
-
-
-
-
- public void setListBean(TableListBean listBean) {
- this.listBean = listBean;
- }
-
-
- private class LocalDataModel extends PagedListDataModel {
- public LocalDataModel(int pageSize) {
- super(pageSize);
- }
-
- public DataPage fetchPage(int startRow, int pageSize) {
-
- return getDataPage(startRow, pageSize);
- }
- }
-
-
- private DataPage getDataPage(int startRow, int pageSize) {
-
-
- List subList = listBean.getTableList(startRow, pageSize);
- DataPage dataPage = new DataPage(listBean.getTotal(), startRow, subList);
- return dataPage;
- }
-
- }
页面的绑定:
- <hx:dataTableEx id="tableEx1" value="#{pagedTableListBean.itemList}"
- var="vartableList" styleClass="dataTableEx" headerClass="headerClass"
- footerClass="footerClass" rowClasses="rowClass1, rowClass2"
- columnClasses="columnClass1" border="1" cellpadding="2"
- cellspacing="0" rows="15">