通过 Objectify / Google App Engine 使用/搜索 AsyncDataProvider

问题描述 投票:0回答:1

我目前有一个使用活动/地点和 AsyncDataProvider 的应用程序。

现在,每次活动加载时,它都会使用请求工厂来检索数据(目前不是很多,但很快就会变得非常大)并将其传递给视图以更新 DataGrid。 在更新之前,它会根据搜索框进行过滤。

现在 - 我已经实现了更新 DataGrid,如下所示:(此代码不是最漂亮的)

private void updateData() {
  final AsyncDataProvider<EquipmentTypeProxy> provider = new AsyncDataProvider<EquipmentTypeProxy>() {

    @Override
    protected void onRangeChanged(HasData<EquipmentTypeProxy> display) {
      int start = display.getVisibleRange().getStart();
      int end = start + display.getVisibleRange().getLength();
      final List<EquipmentTypeProxy> subList = getSubList(start, end);
      end = (end >= subList.size()) ? subList.size() : end;
      if (subList.size() < DATAGRID_PAGE_SIZE) {
        updateRowCount(subList.size(), true);
      } else {
        updateRowCount(data.size(), true);
      }
      updateRowData(start, subList);
    }

    private List<EquipmentTypeProxy> getSubList(int start, int end) {
      final List<EquipmentTypeProxy> filteredEquipment;
      if (searchString == null || searchString.equals("")) {
        if (data.isEmpty() == false && data.size() > (end - start)) {
          filteredEquipment = data.subList(start, end);
        } else {
          filteredEquipment = data;
        }
      } else {
        filteredEquipment = new ArrayList<EquipmentTypeProxy>();
        for (final EquipmentTypeProxy equipmentType : data) {
          if (equipmentType.getName().contains(searchString)) {
            filteredEquipment.add(equipmentType);
          }
        }
      }
      return filteredEquipment;
    }
  };
  provider.addDataDisplay(dataGrid);
} 

最终 - 我想做的只是首先加载必要的数据(此应用程序中的默认页面大小为 25)。

不幸的是,根据我目前的理解,Google App Engine 中的任何 ID 都没有顺序(一个条目的 ID 为 3,下一个条目的 ID 为 4203)。

我想知道,使用 Objectify 时从 Google App Engine 检索数据子集的最佳方法是什么?

我正在研究使用 Offset 和 limit,但另一个堆栈溢出帖子(http://stackoverflow.com/questions/9726232/achieve-good-paging-using-objectify)基本上说这是低效的。

我找到的最好的信息是以下链接(http://stackoverflow.com/questions/7027202/objectify-paging-with-cursors)。 这里的答案说使用游标,但也说这是低效的。 我还使用请求工厂,因此我必须将光标存储在我的用户会话中(如果不正确,请告诉我)。

目前,由于不太可能有大量数据(接下来的几个月可能总共 200 行),我只是将整个数据集拉回到客户端作为临时 hack - 我知道这是最糟糕的方法但希望在浪费时间实施另一个黑客解决方案之前获得最佳方法的输入。 我目前很担心,因为我读过的每一篇关于这样做的文章似乎都没有真正可靠的方法来做到这一点。

我也在考虑做什么 - 目前我的搜索/页面加载速度快如闪电,因为所有数据都已经在客户端。 我在搜索框中使用 KeyUpEvent 处理程序来过滤数据 - 我认为没有任何方法可以通过调用服务器来保持这个速度 - 对于这个问题有任何可接受的解决方案吗?

非常感谢

google-app-engine gwt pagination objectify dataprovider
1个回答
2
投票

使用光标。它们非常高效 - 游标存储上次查询结束的点并从那里继续。您链接的答案实际上没有讨论游标与偏移的效率。 (有一条评论是错误的)

您可以对游标使用 limit - 它不会影响效率。

此外,游标可以通过

cursor.toWebSafeString()
序列化并通过RPC发送到客户端。这样您就不需要将它们保存在会话中。实际上,您还可以将它们用作片段标识符(在 GWT 术语中也称为历史标记)——这样可以为结果集的某个“页面”添加书签。

(Offset 是“低效的”,因为它实际上加载了所有实体,并向您收费,直到 offset+limit,它只返回限制实体)

OTOH,如果您已经知道页面加载时的查询参数,那么只需在页面生成时执行查询,而不是通过 RPC 调用它。另外,如果您有一小部分数据(<1000) you could just preload all entity IDs s part of page html.

© www.soinside.com 2019 - 2024. All rights reserved.