ash*_*shm 6 java database pagination
我看到了很多这种模式.
在服务器上:
// Get a bounded number of results, along with a resume token to use
// for the next call. Successive calls yield a "weakly consistent" view of
// the underlying set that may or may not reflect concurrent updates.
public<T> String getObjects(
int maxObjects, String resumeToken, List<T> objectsToReturn);
Run Code Online (Sandbox Code Playgroud)
在客户端:
// An iterator wrapping repeated calls to getObjects(bufferSize, ...)
public<T> Iterator<T> getIterator(int bufferSize);
Run Code Online (Sandbox Code Playgroud)
大多数地方都推出了这两种方法的自己版本,并且实现起来非常困难.有很多边缘案例错误.
这些查询是否有规范的配方或库?
(您可以对服务器端存储进行一些简化假设,例如T具有自然顺序).
这是使用AbstractIteratorgoogle-guava 库和 spring-jdbc 来实际查询数据库的一个:
public Iterable<T> queryInBatches(
final String query,
final Map<String, Integer> paramMap,
final int pageSize, final Class<T> elementType) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
final Iterator<List<T>> resultIter =
queryResultIterator(query, paramMap, pageSize, elementType);
return new AbstractIterator<T>() {
private Iterator<T> rowSet;
@Override
protected T computeNext() {
if (rowSet == null) {
if (resultIter.hasNext()) {
rowSet = resultIter.next().iterator();
} else {
return endOfData();
}
}
if (rowSet.hasNext()) {
return rowSet.next();
} else {
rowSet = null;
return computeNext();
}
}};
}};
}
private AbstractIterator<List<T>> queryResultIterator(
final String query, final Map<String, Integer> paramMap,
final int pageSize, final Class<T> elementType) {
return new AbstractIterator<List<T>>() {
private int page = 0;
@Override
protected List<T> computeNext() {
String sql = String.format(
"%s limit %s offset %s", query, pageSize, page++ * pageSize);
List<T> results = jdbc().queryForList(sql, paramMap, elementType);
if (!results.isEmpty()) {
return results;
} else {
return endOfData();
}
}};
}
Run Code Online (Sandbox Code Playgroud)
AbstractIterator隐藏了涉及编写您自己的Iterator. 您只需要实现computeNext返回迭代器中的下一个值或调用endOfData以指示迭代器中没有更多值的方法。
| 归档时间: |
|
| 查看次数: |
2004 次 |
| 最近记录: |