【问题标题】:Objectify paging with Cursors使用游标对象化分页
【发布时间】:2011-10-25 00:38:58
【问题描述】:

我的 RPC 服务中有这个方法:

@Override
public Entrata[] getEntrate(int from, int to) {
    List<Entrata> data = entrateDao.list();
    return data.toArray(new Entrata[0]);
}

如您所见,我没有使用这两个参数,在 SQL 世界中,我将其用作 LIMIT 和 OFFSET。

现在还不完全清楚我必须做什么,我开始阅读以下内容: http://code.google.com/p/objectify-appengine/wiki/IntroductionToObjectify#Cursors

我想我必须做一个query.startCursor(&lt;my_"from"_parameter&gt;)

然后迭代“TO”次,即页面大小。

好吗?你能帮我一些sn-ps吗? :)

【问题讨论】:

    标签: java google-app-engine pagination objectify database-cursor


    【解决方案1】:

    来自文档:游标可让您在查询结果集中获取“检查点”,将检查点存储在其他位置,然后从您迟到的地方继续

    由于您只需要限制/偏移量,因此您必须使用 Objectify Query 的 limit()offset() 方法。喜欢:

    ob.query(Entrata.class).limit(to - from).offset(from)
    

    或者,当你有光标时:

    String cursor = // get it from request
    Query<Entrata> query = ob.query(Entrata.class);
    Query q = query.startCursor(Cursor.fromWebSafeString(cursor));
    q.limit(x);
    QueryResultIterator<Entrate> iterator = query.iterator()
    List<Entrate> data = // fetch data
    String newCursor = iterrator.getStartCursor().toWebSafeString()
    return new EntrataListWithCursor(data, cursor);
    

    【讨论】:

    • 效率不高,对不起,我已经知道stackoverflow.com/questions/6861897/objectify-paging 我正在尝试构建一个可以处理数十亿记录的应用程序:-\
    • 如果你知道游标,有没有办法对它们进行限制偏移行为?
    • 如果你已经有一个,你可以从光标开始(光标只是一个序列化的位置)。您打算如何使用这种方法?
    • 你的意思是“已经有一个”?所以,假设我的页面大小是 15。第一个请求,光标为空,所以我迭代数据集的前 15 个元素。然后我抓住光标并将其保存在某处,例如客户的信息。下次我读那个光标的时候,对吧?
    • 好的,所以第一次我将执行“完整”查询并仅迭代 15 次,然后保存游标并将其与数据一起返回给客户端。第二次......类似于你的代码。谢谢 :) 我马上去试试!
    【解决方案2】:

    我只是想确保您的代码中没有任何错误,因为您可以复制并粘贴 Igor Artamonov 代码。 这是来自 Objectify Wiki 的更简洁的代码,错误更少,并且有一些文档:

    // create the query and set the limit to 1000
    Query<Car> query = ofy().load().type(Car.class).limit(1000);
    
    // Here you get the cursor (if exists) from the request
    // For the first request, i-e the first page, this parameter(cursor) will be null
    String cursorStr = request.getParameter("cursor");
    
    // Here you check if cursor is not null and not empty
    // If so, we start our query from the last check point
    if (cursorStr != null && !cursorStr.isEmpty())
        query = query.startAt(Cursor.fromWebSafeString(cursorStr));
    
    // We need this variable to know when we have been loaded all the entries
    boolean remaining = false;
    QueryResultIterator<Car> iterator = query.iterator();
    while (iterator.hasNext()) {
        Car car = iterator.next();
    
        ... // your code here
    
        // We have found entries, so we set this variable to true.
        // That means, we have probably another page to fetch
        remaining = true;
    }
    
    // If we have found entries, we send the last check point
    if (remaining) {
        // we take the last check point by calling "toWebSafeString()" from the iterator's cursor
        Cursor cursor = iterator.getCursor();
        Queue queue = QueueFactory.getDefaultQueue();
        queue.add(url("/pathToThisServlet").param("cursor", cursor.toWebSafeString()));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 2015-09-06
      相关资源
      最近更新 更多