对于Web应用程序,我想实现一个分页表。 DynamoDB“布局”是指用户有多个项目,因此我选择了partition key=user
和sort key=created
(时间戳)。用户界面应显示总共几百个项目中的50个项目中的项目。
通过REST-Api调用将项目传递给UI。我只想query
或scan
一页项目,而不是整个表格。分页应该可以向前和向后。
到目前为止,我已经使用DynamoDBMapper
:
/**
* Returns the next page of items DEPENDENT OF THE USER. Note: This method internally uses
* DynamoDB QUERY. Thus it requires "user" as a parameter. The "created" parameter is optional.
* If provided, both parameters form the startKey for the pagination.
*
* @param user - mandatory: The user for which to get the next page
* @param created - optional: for providing a starting point
* @param limit - the returned page will contain (up to) this number of items
* @return
*/
public List<SampleItem> getNextPageForUser(final String user, final Long created, final int limit) {
// To iterate DEPENDENT on the user we use QUERY. The DynamoDB QUERY operation
// always require the partition key (=user).
final SampleItem hashKeyObject = new SampleItem();
hashKeyObject.setUser(user);
// The created is optional. If provided, it references the starting point
if (created == null) {
final DynamoDBQueryExpression<SampleItem> pageExpression = new DynamoDBQueryExpression<SampleItem>()//
.withHashKeyValues(hashKeyObject)//
.withScanIndexForward(true) //
.withLimit(limit);
return mapper.queryPage(SampleItem.class, pageExpression).getResults();
} else {
final Map<String, AttributeValue> startKey = new HashMap<String, AttributeValue>();
startKey.put(SampleItem.USER, new AttributeValue().withS(user));
startKey.put(SampleItem.CREATED, new AttributeValue().withN(created.toString()));
final DynamoDBQueryExpression<SampleItem> pageExpression = new DynamoDBQueryExpression<SampleItem>()//
.withHashKeyValues(hashKeyObject)//
.withExclusiveStartKey(startKey)//
.withScanIndexForward(true) //
.withLimit(limit);
return mapper.queryPage(SampleItem.class, pageExpression).getResults();
}
}
以前的代码类似,只是它使用withScanIndexForward(false)
。
在我的REST-Api控制器中,我提供了一种方法:
@RequestMapping(value = "/page/{user}/{created}", method = RequestMethod.GET)
public List<SampleDTO> listQueriesForUserWithPagination(//
@RequestParam(required = true) final String user,//
@RequestParam(required = true) final Long created,//
@RequestParam(required = false) final Integer n,//
@RequestParam(required = false) final Boolean isBackward//
) {
final int nrOfItems = n == null ? 100 : n;
if (isBackward != null && isBackward.booleanValue()) {
return item2dto(myRepo.getPrevQueriesForUser(user, created, nrOfItems));
} else {
return item2dto(myRepo.getNextQueriesForUser(user, created, nrOfItems));
}
}
我想知道我是否正在用这种方法重新发明轮子。
是否可以通过REST将DynamoDB的PaginatedQueryList
或PaginatedScanList
传递给UI,这样如果javascript分页访问项目,那么它们会被懒惰地加载。
从与其他数据库合作,我从未传输数据库条目对象,这就是我的代码片段重新打包数据(item2dto
)的原因。
此外,对DynamoDB的分页看起来有点奇怪:到目前为止,我看不到为UI提供项目总数的可能性。因此,UI仅具有“下一页”和“上一页”的按钮,而实际上不知道将跟随多少页。因此无法直接跳到第5页。
答案 0 :(得分:0)
AWS控制台不会立即加载所有数据以节省读取容量。当您获得“扫描/查询”页面时,您只能获得有关如何获取下一页的信息,因此控制台无法向您显示它可以显示多少页数据的原因。根据您的架构,您可以在应用程序中支持随机页面访问。这是通过先决定页面的大小来完成的,然后在分区键中对页面编号进行第二次编码。有关详细信息,请参阅this AWS Forum post。