Spring 数据可分页和 LIMIT/OFFSET

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30217552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:34:07  来源:igfitidea点击:

Spring data Pageable and LIMIT/OFFSET

springjpaspring-dataspring-data-jpa

提问by Mathias

i'm looking at migrating our traditional jpa/dao solution to Spring Data.

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

However, one of our front-ends is SmartGWT, and their databound components load data progressively using limit/offset only, making it hard to use Pageable.

但是,我们的前端之一是 SmartGWT,它们的数据绑定组件仅使用限制/偏移量逐步加载数据,因此很难使用 Pageable。

This causes problems, since it's not certain that the limit/offset can be translated evently into a page number. (it might differ depending on how the user scrolls, screen is resized etc.).

这会导致问题,因为不确定是否可以将限制/偏移量最终转换为页码。(它可能因用户滚动方式、屏幕大小调整等而异)。

I looked at Slice etc, but wasn't able to find a way to use the limit/offset values anywhere.

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

Was wondering if someone has any pointers? Optimally i would like to continue using limit/offset, but use them in my Repository interfaces without having to code an implementation and set them manually like i do now (query.setMaxResults etc.)

想知道是否有人有任何指示?最佳情况下,我想继续使用限制/偏移量,但在我的存储库接口中使用它们,而不必像我现在一样编写实现和手动设置它们(query.setMaxResults 等)

Edit: To clarify why i have issues - The limit/offset might differ between the initial and subsequent data fetches in a smartgwt component. For a listgrid, the first fetch might have limit set to 89 for example, since that's the amount of rows visible on screen, and offset 0. The next request, though, might have offset 89, and limit 50 since that's the component's "datapagesize" value to 50, so that's what it'll fetch when i scroll down. If i scroll to far down before releasing, it might, depending on the settings, fetch for example rows 159-209 instead. Basically, there's no guarantee that the offset is a multiple of anything. It's hard to convert offset 17, limit 5 to a page.

编辑:澄清为什么我有问题 - smartgwt 组件中的初始和后续数据提取之间的限制/偏移量可能不同。对于列表网格,例如,第一次获取可能将限制设置为 89,因为这是屏幕上可见的行数,偏移量为 0。不过,下一个请求可能具有偏移量 89,限制为 50,因为这是组件的“数据页面大小” " 值为 50,所以当我向下滚动时,它会获取到的值。如果我在发布之前向下滚动到很远的地方,它可能会根据设置而获取例如第 159-209 行。基本上,不能保证偏移量是任何东西的倍数。很难将偏移量 17,限制为 5 转换为一页。

回答by woemler

Pagebale implementations douse limitand offsetto create pagination. The pagevalue in the constructor is used to generate the offset value in the AbstractPageRequestclass getOffsetmethod:

Pagebale 实现确实使用limitoffset创建分页。的page在构造值被用于生成在所述偏移值AbstractPageRequest的类getOffset的方法:

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

If you want to only use limitand offsetand discard the pageparameter from the mix, take a look at the Spring Data documentation on web support, particularly the part about overriding the default configuration. You could create your own implementation of Pageablethat takes limitand offsetas constructor arguments and the implement your own HandlerMethodArgumentResolverto replace the standard PageRequestresolving. Quick-and-dirty example:

如果您只想使用limitoffset丢弃page混合中的参数,请查看Web 支持的 Spring Data 文档,特别是关于覆盖默认配置的部分。您可以创建自己的实现Pageablelimit并将其offset作为构造函数参数,并实现您自己HandlerMethodArgumentResolver的替换标准PageRequest解析。快速而肮脏的例子:

Pageable implementation

分页实现

public class BetterPageRequest implements Pageable {

    public BetterPageRequest(int limit, int offset){
        this.limit = limit;
        this.offset = offset;
    }

    // Other method implementations

}

HandlerMethodArgumentResolver implementation

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

}

回答by Almas Abdrazak

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

And example

和例子

Page<WashComment> washComments = washCommentRepository.findWashCommentByWashId_CarWashIdOrderByDateDesc(carWash, new OffsetLimitPageable(offsetNumberRepresentation,
                 limitNumberRepresentation > Config.getMaxLimitAmount() ? Config.getMaxLimitAmount() : limitNumberRepresentation));

Let me know if it what you want

让我知道你想要什么