1

我有一个庞大的对象列表,每个对象都包含许多图像。我想使用延迟加载来部分获取它们。我想了解如何使用 LazyDataModel 以及它是如何工作的。

最初我认为我只需要在LazyDataModel中保存可能获取的对象的id 。当调用 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.springframework.webflow.conversation.impl.LockTimeoutException:30 秒后无法获取对话锁

最后我明白了 LazyDataModel 的 primefaces 示例(其中保存到datasource的完整数据列表,包括所有图像)可能是正确的使用方式。因为最初我认为它是简化的虚拟示例,在实际项目中我将使用 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 如何工作并提高性能。如果使用这种方法的正确方法是从 DB 中检索所有数据并将其保存到datasource。Primefaces 是否将这些数据保存在服务器上并部分刷新?如果 sql 结果包含数千张图片,我应该寻找不同的方法并设置检索记录的限制吗?如何实现最好的延迟加载性能提升?或者也许最初的方法是正确的,我应该调查为什么会发生这个错误?

4

1 回答 1

-2

好的,我终于做到了,每次触发 load() 方法时我应该执行查询的想法是正确的。

我面临的问题:

  1. 如果我只返回查询的结果 - load() 方法只触发一次,我无法加载更多数据。所以我使用 dummy 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());
}
于 2018-10-05T11:16:57.883 回答