Google 云端点中的分页 + 数据存储 + Objectify

Pagination in Google cloud endpoints + Datastore + Objectify

我想 return 来自具有可选分页的端点的 "Posts" 列表。 每个查询需要 100 个结果。 我写的代码如下,它似乎不起作用。 我指的是 Objectify Wiki

中的示例

我知道的另一个选择是使用 query.offset(100); 但我在某处读到这只会加载整个 table 然后忽略前 100 个不是最佳的条目。

我想这一定是一个常见的用例,并且会有一个最佳解决方案。

public CollectionResponse<Post> getPosts(@Nullable @Named("cursor") String cursor,User auth) throws OAuthRequestException {
        if (auth!=null){

            Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").limit(100);

            if (cursor!=null){
                query.startAt(Cursor.fromWebSafeString(cursor));
                log.info("Cursor received :" + Cursor.fromWebSafeString(cursor));
            } else {
                log.info("Cursor received : null");
            }

            QueryResultIterator<Post> iterator = query.iterator();

            for (int i = 1 ; i <=100 ; i++){
                if (iterator.hasNext()) iterator.next();
                else break;
            }

            log.info("Cursor generated :" + iterator.getCursor());

            return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(iterator.getCursor().toWebSafeString()).build();

        } else throw new OAuthRequestException("Login please.");
    }

这是一个使用 Offsets 的代码,似乎工作正常。

@ApiMethod(
            name = "getPosts",
            httpMethod = ApiMethod.HttpMethod.GET
    )
    public CollectionResponse<Post> getPosts(@Nullable @Named("offset") Integer offset,User auth) throws OAuthRequestException {
        if (auth!=null){

            if (offset==null) offset = 0;

            Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").offset(offset).limit(LIMIT);

            log.info("Offset received :" + offset);
            log.info("Offset generated :" + (LIMIT+offset));

            return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(String.valueOf(LIMIT + offset)).build();

        } else throw new OAuthRequestException("Login please.");
    }

尝试以下操作:

  1. 删除您的 for 循环——不确定它为什么在那里。但只需遍历您的列表并构建您要发回的项目列表。您应该坚持使用迭代器,而不是在一个循环中强制使用 100 个项目。
  2. 接下来,一旦你遍历了它,使用 iterator.getStartCursor() 作为游标的值。

一定要分配查询:

query = query.startAt(cursor);

Objectify 的 API 使用函数式风格。 startAt() 不改变对象。