我需要以下设计方面的帮助。我公开了一个从数据库中执行SQL select
的Web方法。问题是记录的数量可能很大,我不想在一次通话中返回所有记录
所以我可以考虑这些选项(在页面中返回结果):
1)提供一个带参数的方法,以便客户每次都要求recordStart
和recordEnd
2)修改方法以接受大小为X
的结果集,并以某种方式理解每个请求不是新请求,但返回下一个X
记录。为了解决这个问题,可以将每个客户端的某个令牌关联起来,但问题是我不确定该令牌应保留多长时间然后处理,以便将传入请求视为第一个请求或前一个请求的延续一。
那么我应该选择哪种设计?如何解决我提到的任何相关问题? 有没有更好的方法来处理这些问题?
答案 0 :(得分:2)
从我的观点来看:
您在数据库上执行选择的界面类似于:
public PageResponse getPage(PageRequest pageRequest);
这种方法很容易扩展您的分页方法,想象在几个月内您需要对该方法实现排序,您需要将每次调用更改为它。使用这种方法,您可以更改PageRequest
对象并提供默认排序,不会破坏任何内容,您可以在真正需要它的调用中自定义排序。
在此方法中,您将需要两个不同的数据库选择:
top
对于sybase,limit
用于mysql和PG,rownum
用于Oracle,这将因数据库而异;)对您的问题的一个很好的参考是Spring Data,他们Page和PageRequest或多或少都是您需要的。也许你可以使用他们的API来实现你的解决方案。
实际上您的请求对象可能如下所示:
public class PageRequest {
private int offset;
private int pageSize;
// getters and setters and convenience constructors with the given fields
}
public class PageResponse {
private List<?> resultList;
private int total;
// getters and setters and convenience constructors with the given fields
}
当然,您也可以使用Generics,以便拥有您已经请求的响应保持类型,以便于使用响应对象,如:
public <T> PageResponse<T> getPage(PageRequest<T> pageRequest);
具有请求和响应的对象,如:
public class PageRequest<T> {
private int offset;
private int pageSize;
// getters and setters and convenience constructors with the given fields
}
public class PageResponse<T> {
private List<T> resultList;
private int total;
// getters and setters and convenience constructors with the given fields
}
答案 1 :(得分:0)
更好的方法和最广泛使用的方法是1)
。
在这种情况下,sql过程和客户端代码之间没有约束(就像根据OOP中的接口编程一样)。
然后查看令牌所在的哈希值也很简单且不易出错,因此您可以获取当前位置。您还必须在某处记住此哈希值(内存用于速度或磁盘用于持久性)。
正如你所看到的,这种方法很复杂,如果你仔细思考它,你必须做出比第一种方法更多的决定。
此外,第一种方法使您可以更自由地设计应用程序b / c,它的行为类似于OOP封装。对于将来,您还可以使用另一段代码来记住您当前的位置,客户端将调用此代码,然后此代码将调用数据库将结果传递给客户端。
最后一行,请使用1)
。
答案 2 :(得分:0)
如果您想要返回结果总数,我会选择两个选项的组合:
最好的方法是将查询(没有分页部分)与标识符一起保留,这样您甚至不必在下次调用时再次创建它。