【问题标题】:Spring data Pageable and LIMIT/OFFSETSpring 数据可分页和 LIMIT/OFFSET
【发布时间】:2015-07-24 21:38:43
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 不限制=大小,偏移量只是页面*大小?哪个是默认的 Pageable 实现?
  • 不,因为它可能会有所不同。假设我有一个 Listgrid。 SmartGWT 逻辑最初会将偏移设置为 0,并设置一个足够大的限制来加载屏幕上可以看到的内容。这可以是 50、79、99 等,具体取决于屏幕大小、浏览器大小等。下一次,它将使用“pagesize”值,例如可能是 50。然后,根据您的滚动方式,下一次可能例如,获取第 250-300 行。我的问题是我无法控制初始 LIMIT 值,基本上,smartgwt 也无法决定偏移量在后续请求中。

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


【解决方案1】:

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

}

【讨论】:

  • 啊,实现我自己的 Pageable 可能是我可以尝试的东西,谢谢!由于 LIMIT/OFFSET 是一个主要的数据库概念,我觉得它没有现成的提供有点奇怪。
  • 但是您的代码实际上突出了为什么我在分页时遇到问题并创建了这个问题!例如,如果我收到偏移量为 17 且限制为 5 的请求怎么办?
  • 我有点明白你在做什么,虽然我自己从未尝试过这样的事情,所以有点担心我会永远花时间让它工作:)。我想我也可以扩展 AbstractPageRequest 并让它在“getpagesize”中返回限制并在 getOffset 中返回偏移量。然后在我需要的任何地方都只是我的自定义页面请求。
  • 配置和实现应该不会太难。这样做的好处是不需要更改以Pageable 作为参数的方法的存储库功能,并且控制器中不需要额外的代码来处理您的Pageable 版本。如果您使用的是 Spring HATEOAS,这也会很有用。
  • 是的......结果它不起作用。 smartGWT 设置限制和偏移量,他们将它们称为“startrow”和“endrow”作为 http 正文中的参数。在我迁移到他们的“restservice”之前,无论如何我都必须自己从请求中挖掘出来。不过,我会保留这个以备将来使用,谢谢!
【解决方案2】:
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));

如果这是你想要的,请告诉我

【讨论】:

  • 不错的解决方法。但值得一提的是,previous()next() 等其他 PageRequest 方法将无法正常工作。所以,OffsetLimitPageable 的实例并不是PageRequest 的完整实现。
  • 我在这里得到了答复stackoverflow.com/a/63911746/2740179
猜你喜欢
  • 2020-12-30
  • 2013-12-20
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 2011-07-27
  • 2020-08-19
  • 2011-09-12
相关资源
最近更新 更多