Spring 数据可分页和 LIMIT/OFFSET
Spring data Pageable and LIMIT/OFFSET
我正在考虑将我们的传统 jpa/dao 解决方案迁移到 Spring 数据。
但是,我们的前端之一是 SmartGWT,它们的数据绑定组件仅使用 limit/offset 逐步加载数据,因此很难使用 Pageable。
这会导致问题,因为不确定 limit/offset 能否最终转换为页码。 (它可能会因用户滚动方式、屏幕大小调整等方式而有所不同)。
我查看了 Slice 等,但无法找到在任何地方使用 limit/offset 值的方法。
想知道是否有人有任何指示?最理想的是,我想继续使用 limit/offset,但在我的 Repository 接口中使用它们,而不必编写实现代码并像我现在那样手动设置它们(query.setMaxResults 等)
编辑:澄清我遇到问题的原因 - limit/offset 可能在 smartgwt 组件中的初始和后续数据提取之间有所不同。例如,对于 listgrid,第一次获取可能将限制设置为 89,因为这是屏幕上可见的行数,偏移量为 0。不过,下一个请求可能有偏移量 89,并且限制为 50,因为这是组件的 "datapagesize" 值设置为 50,这就是我向下滚动时获取的值。
如果我在发布之前滚动到最下方,它可能会根据设置获取例如第 159-209 行。基本上,不能保证偏移量是任何值的倍数。很难将偏移量17,限制5转换为一页。
Pagebale 实现 do 使用 limit
和 offset
创建分页。构造函数中的page
值用于在AbstractPageRequest
classgetOffset
方法中生成偏移值:
public int getOffset() {
return this.page * this.size;
}
如果您只想使用 limit
和 offset
并从组合中丢弃 page
参数,请查看 the Spring Data documentation on web support,尤其是关于覆盖的部分默认配置。您可以创建自己的 Pageable
实现,将 limit
和 offset
作为构造函数参数,并实现您自己的 HandlerMethodArgumentResolver
来替换标准 PageRequest
解析。简单的例子:
可分页实现
public class BetterPageRequest implements Pageable {
public BetterPageRequest(int limit, int offset){
this.limit = limit;
this.offset = offset;
}
// Other method implementations
}
HandlerMethodArgumentResolver 实现
public class BetterPageableResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter){
return Pageable.class.equals(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request, WebDataBinderFactory factory){
Map<String,String[]> params = request.getParameterMap();
return new BetterPageRequest(params.get('limit')[0], params.get('offset')[0]);
}
}
public class OffsetLimitPageable extends PageRequest {
private int offset;
public OffsetLimitPageable(int offset, int limit){
super(offset,limit);
this.offset=offset;
}
@Override
public long getOffset(){
return this.offset;
}
}
和例子
Page<WashComment> washComments = washCommentRepository.findWashCommentByWashId_CarWashIdOrderByDateDesc(carWash, new OffsetLimitPageable(offsetNumberRepresentation,
limitNumberRepresentation > Config.getMaxLimitAmount() ? Config.getMaxLimitAmount() : limitNumberRepresentation));
如果这是你想要的,请告诉我
我正在考虑将我们的传统 jpa/dao 解决方案迁移到 Spring 数据。
但是,我们的前端之一是 SmartGWT,它们的数据绑定组件仅使用 limit/offset 逐步加载数据,因此很难使用 Pageable。
这会导致问题,因为不确定 limit/offset 能否最终转换为页码。 (它可能会因用户滚动方式、屏幕大小调整等方式而有所不同)。
我查看了 Slice 等,但无法找到在任何地方使用 limit/offset 值的方法。
想知道是否有人有任何指示?最理想的是,我想继续使用 limit/offset,但在我的 Repository 接口中使用它们,而不必编写实现代码并像我现在那样手动设置它们(query.setMaxResults 等)
编辑:澄清我遇到问题的原因 - limit/offset 可能在 smartgwt 组件中的初始和后续数据提取之间有所不同。例如,对于 listgrid,第一次获取可能将限制设置为 89,因为这是屏幕上可见的行数,偏移量为 0。不过,下一个请求可能有偏移量 89,并且限制为 50,因为这是组件的 "datapagesize" 值设置为 50,这就是我向下滚动时获取的值。 如果我在发布之前滚动到最下方,它可能会根据设置获取例如第 159-209 行。基本上,不能保证偏移量是任何值的倍数。很难将偏移量17,限制5转换为一页。
Pagebale 实现 do 使用 limit
和 offset
创建分页。构造函数中的page
值用于在AbstractPageRequest
classgetOffset
方法中生成偏移值:
public int getOffset() {
return this.page * this.size;
}
如果您只想使用 limit
和 offset
并从组合中丢弃 page
参数,请查看 the Spring Data documentation on web support,尤其是关于覆盖的部分默认配置。您可以创建自己的 Pageable
实现,将 limit
和 offset
作为构造函数参数,并实现您自己的 HandlerMethodArgumentResolver
来替换标准 PageRequest
解析。简单的例子:
可分页实现
public class BetterPageRequest implements Pageable {
public BetterPageRequest(int limit, int offset){
this.limit = limit;
this.offset = offset;
}
// Other method implementations
}
HandlerMethodArgumentResolver 实现
public class BetterPageableResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter){
return Pageable.class.equals(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request, WebDataBinderFactory factory){
Map<String,String[]> params = request.getParameterMap();
return new BetterPageRequest(params.get('limit')[0], params.get('offset')[0]);
}
}
public class OffsetLimitPageable extends PageRequest {
private int offset;
public OffsetLimitPageable(int offset, int limit){
super(offset,limit);
this.offset=offset;
}
@Override
public long getOffset(){
return this.offset;
}
}
和例子
Page<WashComment> washComments = washCommentRepository.findWashCommentByWashId_CarWashIdOrderByDateDesc(carWash, new OffsetLimitPageable(offsetNumberRepresentation,
limitNumberRepresentation > Config.getMaxLimitAmount() ? Config.getMaxLimitAmount() : limitNumberRepresentation));
如果这是你想要的,请告诉我