Spring数据可分页和LIMIT / OFFSET

时间:2015-05-13 14:16:27

标签: spring jpa spring-data spring-data-jpa

我正在考虑将传统的jpa / dao解决方案迁移到Spring Data。

然而,我们的一个前端是SmartGWT,它们的数据绑定组件仅使用限制/偏移量逐步加载数据,这使得很难使用Pageable。

这会导致问题,因为不能确定限制/偏移是否可以最终转换为页码。 (它可能会有所不同,具体取决于用户如何滚动,调整屏幕大小等。)

我查看了Slice等,但无法找到在任何地方使用限制/偏移值的方法。

想知道是否有人指点?最好我想继续使用limit / offset,但是在我的Repository接口中使用它们而不必编写实现并像我现在那样手动设置它们(query.setMaxResults等。)

编辑:澄清我遇到问题的原因 - 在smartgwt组件中初始和后续数据提取之间的限制/偏移可能不同。对于listgrid,第一次获取可能将限制设置为89,例如,因为这是屏幕上可见的行数,并且偏移量为0.但是,下一个请求可能具有偏移量89,并且限制为50,因为这是组件的“datapagesize” “值为50,这就是我向下滚动时所取的东西。 如果我在发布之前滚动到远处,它可能会取决于设置,例如取代行159-209。基本上,不能保证偏移量是任何东西的倍数。将偏移17,限制5转换为页面很难。

2 个答案:

答案 0 :(得分:12)

Pagebale实现执行使用limitoffset来创建分页。构造函数中的page值用于在AbstractPageRequestgetOffset方法中生成偏移值:

public int getOffset() {
    return this.page * this.size;
}

如果您只想使用limitoffset并放弃混合中的page参数,请查看the Spring Data documentation on web support,特别是关于覆盖默认值的部分组态。您可以创建自己的Pageable实现,将limitoffset作为构造函数参数,并实现您自己的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]);
    }

}

答案 1 :(得分:9)

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));

让我知道你想要的是什么