RichFaces ExtendedTableDataModel: сортировка столбцов извлекает все строки - PullRequest
4 голосов
/ 14 сентября 2010

Мы используем ExtendedTableDataModel для подкачки.Это делается для получения набора результатов с помощью Hibernate и загрузки следующего набора при запросе другой страницы.

Все работает нормально, но если мы сортируем столбцы с помощью rich: column sortBy внутри rich: dataTable, тогда RichFaces пытается загрузить все строки.Мы можем видеть это при отладке getItemsByRange, который мы сделали для нашего пользовательского DataProvider.После однократного нажатия кнопки сортировки RichFaces продолжит извлекать все строки из базы данных.Это, конечно, не то, что мы хотим.Мы хотели использовать это решение для минимизации трафика данных и времени загрузки.

Мы используем Richfaces 3.3.2.Есть ли кто-нибудь с возможным решением или обходным путем?

1 Ответ

4 голосов
/ 17 сентября 2010

У нас была та же проблема, и вот наше решение.Я не совсем уверен, что весь код, который я вставляю, уместен, но он должен быть

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