【问题标题】:Using/Searching AsyncDataProvider with Objectify / Google App Engine通过 Objectify / Google App Engine 使用/搜索 AsyncDataProvider
【发布时间】:2012-06-14 20:28:27
【问题描述】:

我目前有一个使用活动/地点和 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 行),我只是将整个数据集作为临时黑客撤回给客户端 - 我知道这是最糟糕的方式这样做,但想在浪费我的时间实施另一个黑客解决方案之前获得最好的方法。我目前很担心,因为似乎我读过的每一篇关于这样做的文章都让人觉得似乎没有真正可靠的方法来做到这一点。

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

非常感谢

【问题讨论】:

    标签: google-app-engine gwt paging objectify dataprovider


    【解决方案1】:

    使用光标。它们尽可能高效 - 游标存储最后一个查询结束的点并从那里继续。您链接的答案实际上并未讨论游标与偏移的效率。 (有评论有误)

    您可以将限制与游标一起使用 - 它不会影响效率。

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

    (偏移量是“低效的”,因为它实际加载并向您收费,对于直到偏移量+限制的所有实体,它只返回限制实体)

    OTOH,如果您在页面加载时已经知道查询参数,那么只需在页面生成时进行查询,而不是通过 RPC 调用它。此外,如果您有一小部分数据(

    【讨论】:

    • 当您说序列化游标并通过 RPC 将其发送到客户端时 - 您可以在使用 RequestFactory 时执行此操作吗?如果是这样的话,任何地方都有这样的例子 - 我认为按照你提到的方式来做这件事会非常好,因为它可以让我准确地知道客户停止的位置(例如,如果活动重新加载,我们从头开始,而如果用户只是我们使用发送到客户端的序列化光标来获取确切的点) - 我不确定如何使用我当前的请求工厂设置来做到这一点
    猜你喜欢
    • 2011-06-19
    • 2014-08-09
    • 2012-05-05
    • 1970-01-01
    • 2014-08-05
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多