App Engine Java: syntax for setting query limit and start offset.
I have a list of games in GAE datastore and I want to query fixed number of them, starting from a certain offset, i.e. get next 25 games starting form entry with id "75".
PersistenceManager pm = PMF.get().getPersistenceManager(); // from Google examples
Query query = pm.newQuery(Game.class); // objects of class Game are stored in datastore
query.setOrdering("creationDate asc");
/* querying for open games, not created by this player */
query.setFilter("state == Game.STATE_OPEN && serverPlayer.id != :playerId");
String playerId = "my-player-id";
List<Game> games = query.execute(playerId); // if there's lots of games, returned list has more entries, than user needs to see at a time
//...
Now I need to extend that query to fetch only 25 games and only games following entry with id "75". So the user can browse for open games, fetching only 25 of them at a time. I know there's lot开发者_如何学Cs of examples for GAE datastore, but those all are mostly in Python, including sample code for setting limit on the query. I am looking for a working Java code sample and couldn't find one so far.
It sounds like you want to facilitate paging via Query Cursors. See: http://code.google.com/appengine/docs/java/datastore/queries.html#Query_Cursors
From the Google doc:
public class ListPeopleServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("Person");
PreparedQuery pq = datastore.prepare(q);
int pageSize = 15;
resp.setContentType("text/html");
resp.getWriter().println("<ul>");
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(pageSize);
String startCursor = req.getParameter("cursor");
// If this servlet is passed a cursor parameter, let's use it
if (startCursor != null) {
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor));
}
QueryResultList<Entity> results = pq.asQueryResultList(fetchOptions);
for (Entity entity : results) {
resp.getWriter().println("<li>" + entity.getProperty("name") + "</li>");
}
resp.getWriter().println("</ul>");
String cursor = results.getCursor().toWebSafeString();
// Assuming this servlet lives at '/people'
resp.getWriter().println(
"<a href='/people?cursor=" + cursor + "'>Next page</a>");
}
}
Thanks everyone for help. The cursors was the right answer. The thing is that I am pretty much stuck with JDO and can't use DatastoreService, so I finally found this link: http://code.google.com/appengine/docs/java/datastore/jdo/queries.html#Query_Cursors
精彩评论