我们使用ExtendedTableDataModel进行分页。这样做是为了使用Hibernate检索一组结果,并在请求另一个页面时加载下一组。
一切正常,但是如果我们在rich:dataTable中使用rich:column sortBy对列进行排序,那么RichFaces会尝试加载所有行。我们可以在调试我们为自定义DataProvider制作的getItemsByRange时看到这一点。单击排序一次后,RichFaces将继续从数据库中检索所有行。这当然不是我们想要的。我们希望使用此解决方案来最小化数据流量和加载时间。
我们使用Richfaces 3.3.2。是否有人有可能的解决方案或解决方法?
答案 0 :(得分:4)
我们遇到了同样的问题,这是我们的解决方案。我不完全确定我粘贴的整个代码是相关的,但它应该是
public class PagingExtendedTableDataModel<T> extends ExtendedDataModel implements
Serializable, Modifiable {
private DataProvider dataProvider;
private Object rowKey;
private List wrappedKeys;
private Map wrappedData;
private Integer rowCount;
private Integer rowIndex;
private List<FilterField> filterFields;
private List<SortField2> sortFields;
public PagingExtendedTableDataModel(DataProvider<T> dataProvider) {
wrappedKeys = null;
wrappedData = new HashMap();
rowCount = null;
rowIndex = Integer.valueOf(-1);
rowKey = null;
this.dataProvider = dataProvider;
}
public Object getRowKey() {
return rowKey;
}
public void setRowKey(Object key) {
rowKey = key;
}
@SuppressWarnings("unchecked")
public void walk(FacesContext context, DataVisitor visitor, Range range,
Object argument) throws IOException {
int rowC = getRowCount();
int firstRow = ((SequenceRange) range).getFirstRow();
int numberOfRows = ((SequenceRange) range).getRows();
if (numberOfRows <= 0) {
numberOfRows = rowC;
}
if (wrappedKeys != null) {
Object key;
for (Iterator it = wrappedKeys.iterator(); it.hasNext();
visitor.process(context, key, argument)) {
key = it.next();
setRowKey(key);
}
} else {
wrappedKeys = new ArrayList();
int endRow = firstRow + numberOfRows;
if (endRow > rowC) {
endRow = rowC;
}
if (dataProvider instanceof Sortable2) {
((Sortable2) dataProvider).setSortFields(sortFields);
}
if (dataProvider instanceof Filterable) {
((Filterable) dataProvider).setFilterFields(filterFields);
}
Object key;
for (Iterator it = loadData(firstRow, endRow).iterator(); it.hasNext();
visitor.process(context, key, argument)) {
Object item = it.next();
key = getKey(item);
wrappedKeys.add(key);
wrappedData.put(key, item);
}
}
}
protected List loadData(int startRow, int endRow) {
if (startRow < 0) {
startRow = 0;
throw new IllegalArgumentException((new StringBuilder()).append(
"Illegal start index value: ").append(startRow).toString());
}
int rowCount = getRowCount();
if (endRow > rowCount) {
endRow = rowCount;
throw new IllegalArgumentException((new StringBuilder()).append(
"Illegal end index value: ").append(endRow).toString());
}
return dataProvider.getItemsByRange(startRow, endRow);
}
public int getRowCount() {
if (rowCount == null) {
rowCount = new Integer(dataProvider.getRowCount());
} else {
return rowCount.intValue();
}
return rowCount.intValue();
}
public Object getRowData() {
if (rowKey == null) {
return null;
}
return getObjectByKey(rowKey);
}
@SuppressWarnings("unchecked")
public Object getKey(Object o) {
return dataProvider.getKey(o);
}
@SuppressWarnings("unchecked")
public Object getObjectByKey(Object key) {
Object t = wrappedData.get(key);
if (t == null) {
t = dataProvider.getItemByKey(key);
wrappedData.put(key, t);
}
return t;
}
public int getRowIndex() {
return rowIndex.intValue();
}
public void setRowIndex(int rowIndex) {
this.rowIndex = Integer.valueOf(rowIndex);
}
public Object getWrappedData() {
throw new UnsupportedOperationException();
}
public void setWrappedData(Object data) {
throw new UnsupportedOperationException();
}
public boolean isRowAvailable() {
return getRowData() != null;
}
public void reset() {
wrappedKeys = null;
wrappedData.clear();
rowCount = null;
rowIndex = Integer.valueOf(-1);
rowKey = null;
}
public DataProvider getDataProvider() {
return dataProvider;
}
public void setDataProvider(DataProvider dataProvider) {
this.dataProvider = dataProvider;
}
@Override
public void modify(List<FilterField> filterFields, List<SortField2> sortFields) {
this.filterFields = filterFields;
this.sortFields = sortFields;
reset();
}
}
您还需要自定义DataProvider
public class PagingDataProvider implements DataProvider<BeanDisplay>,
Sortable2, Filterable
在方法getItemsByRange
中,使查询仅加载有限数量的记录。所有其他方法应该直接实现(我没有粘贴我们的代码,因为它充满了非常具体的代码,这是不相关的)
您可以按如下方式构建数据模型:
new PagingExtendedTableDataModel<BeanDisplay>(new PagingDataProvider());