Primefaces LazyDataModel: правильный способ использования - PullRequest
0 голосов
/ 05 октября 2018

У меня огромный список объектов, каждый из которых содержит количество изображений.Я хочу использовать ленивую загрузку, чтобы получить их частично.И я хочу понять, как использовать LazyDataModel и как он работает.

Сначала я подумал, что мне нужно сохранить только идентификаторы потенциально извлеченных объектов внутри LazyDataModel при вызове метода load () - мне нужно извлечь изображения из БД и заменить источник данных извлеченными данными.Поэтому каждый раз, когда я хочу загрузить больше данных, я запускаю запрос.

private List<MyEntity> datasource; // contains only ids of MyEntity

@Override
public List<MyEntity> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
    //rowCount
    int dataSize = datasource.size();
    this.setRowCount(dataSize);

    //get listOfIdToFetch

    //paginate
    datasource = datasource.addAll(myJpaRepository.findByIds(listOfIdToFetch));
    return datasource;
}

Я не мог заставить его работать, потому что Primefaces использовал метод lock () и генерировал исключение, когда новая часть данных должна была быть загружена:

org.* полный список данных, сохраненных в источник данных , включая все изображения ), может быть правильным способом использования.Поскольку изначально я думал, что это упрощенный фиктивный пример, и в реальном проекте я буду использовать sql-запросы для выборки изображений по частям.

private List<MyEntity> datasource; // contains all images of all records
@Override
public List<MyEntity> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
    //rowCount
    int dataSize = datasource.size();
    this.setRowCount(dataSize);

    //paginate
    return datasource.subList(first, first + pageSize);
}

Я хочу понять, как работает LazyDataModel и повышает производительность.Если правильный способ использования этого подхода - извлечь все данные из БД и сохранить их в источник данных .Сохраняет ли Primefaces эти данные на сервере и сбрасывает их по частям? Что, если результат sql содержит тысячи изображений , стоит ли искать другой подход и устанавливать лимит извлекаемых записей?Как добиться лучшего увеличения производительности при отложенной загрузке?Или, возможно, первоначальный подход правильный, и я должен выяснить, почему возникает эта ошибка?

1 Ответ

0 голосов
/ 05 октября 2018

Хорошо, я наконец-то сделал это, и идея, что я должен выполнять запрос каждый раз при запуске метода load () , была правильной.

Проблемы, с которыми я сталкиваюсь:

  1. Если я просто возвращаю результат моего запроса - метод load () запускается только один раз , и я не могу загрузитьбольше данных.Поэтому я использую фиктивный sublist (0, chunkSize) .
  2. Я не смог @Autowire мой репозиторий , у меня было исключение, что некоторые объекты не сериализованы.Но я мог бы использовать EntityManager , и я так и сделал.

Исходный код:

private List<MyEntity> datasource; // contains only ids

@Override
public List<MyEntity> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
        StringBuilder queryText = new StringBuilder("select ...");
        List<MyEntity> list;

        //paginate
        if(datasource.size() > pageSize) {
            try {
                list = new ArrayList<>(datasource.subList(first, first + pageSize));
            }
            catch(IndexOutOfBoundsException e) {
                list = new ArrayList<>(datasource.subList(first, first + (datasource.size() % pageSize)));
            }
        }
        else {
            list = new ArrayList<>(datasource);
        }

        boolean setComa = false;
        for (MyEntity a: list) {
            if (setComa) {
                queryText.append(","+a.getId());
            } else {
                queryText.append(a.getId());
                setComa = true;
            }
        }
        queryText.append(")");
        Query q = em.createQuery(queryText.toString());
        list = q.getResultList();
        return list.subList(0, list.size());
}

ОГРАНИЧЕНИЕ ОБНОВЛЕНИЯ:

@Override
public List<MyEntity> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {

    List<MyEntity> list;

    Query q = em.createQuery(this.queryText);

    // Paginate
    q.setFirstResult(first); 
    q.setMaxResults(pageSize); 
    list = query.getResultList();

    return list.subList(0,list.size());
}
...