Ответ 1
При переходе на следующую страницу вы можете упростить вариант использования, разрешив только "следующую страницу", а не произвольный пейджинг. Вы можете сделать это в SimpleDB, используя предложение LIMIT:
SELECT title, summary, votecount FROM posts WHERE userid = '000022656' LIMIT 25
Вы уже знаете, как обращаться с NextToken, но если вы используете эту тактику, вы можете поддержать "предыдущую страницу", сохранив тропку для следующих маркеров (например, в веб-сеансе) и повторно отправив запрос с предыдущей NextToken, а не следующий.
Однако общий случай обработки произвольной разбивки на страницы в SimpleDB одинаковый для предыдущего и следующего. В общем случае пользователь может щелкнуть по произвольному номеру страницы, например 5, без посещения страницы 4 или 6.
Вы обрабатываете это в SimpleDB, используя тот факт, что NextToken требует, чтобы условие WHERE было одинаковым для правильной работы. Поэтому вместо того, чтобы запрашивать каждую страницу в последовательности, отбрасывая все промежуточные элементы, вы обычно можете сделать это за два шага.
- Задайте свой запрос с предельным значением, где должна начинаться требуемая страница, и SELECT count (*) вместо фактических атрибутов, которые вы хотите.
- Используйте NextToken с первого шага для получения фактических данных страницы с использованием желаемых атрибутов и размера страницы в качестве параметра LIMIT
Итак, в псевдокоде:
int targetPage, pageSize;
...
int jumpLimit = pageSize * (targetPage - 1);
String query = "SELECT %1 FROM posts WHERE userid = '000022656' LIMIT %2";
String output = "title, summary, votecount";
Result temp = sdb.select(query, "count(*)", jumpLimit);
Result data = sdb.select(query, output, pageSize, temp.getToken());
Где% 1 и% 2 являются строковыми подстановками, а "sdb.select()" - это фиктивный метод, который включает в себя код замены String вместе с вызовом SimpleDB.
Можно ли выполнить это в двух вызовах SimpleDB (как показано в коде), будет зависеть от сложности вашего предложения WHERE и размера вашего набора данных. Вышеприведенный код упрощен тем, что результат temp может возвращать частичный счет, если запрос занял более 5 секунд для запуска. Вы действительно хотели бы поставить эту строку в цикле, пока не будет достигнут правильный счет. Чтобы сделать код более реалистичным, я поставлю его в методы и избавлюсь от подстановок String:
private Result fetchPage(String query, int targetPage)
{
int pageSize = extractLimitValue(query);
int skipLimit = pageSize * (targetPage - 1);
String token = skipAhead(query, skipLimit);
return sdb.select(query, token);
}
private String skipAhead(String query, int skipLimit)
{
String tempQuery = replaceClause(query, "SELECT", "count(*)");
int accumulatedCount = 0;
String token = "";
do {
int tempLimit = skipLimit - accumulatedCount;
tempQuery = replaceClause(tempQuery , "LIMIT", tempLimit + "");
Result tempResult = sdb.select(query, token);
token = tempResult.getToken();
accumulatedCount += tempResult.getCount();
} while (accumulatedCount < skipLimit);
return token;
}
private int extractLimitValue(String query) {...}
private String replaceClause(String query, String clause, String value){...}
Это общая идея без обработки ошибок и работает для любой произвольной страницы, исключая страницу 1.