Spring данные jpa limit pagesize, как установить maxSize

У меня есть одно требование - искать по страницам и без страницы,

и в моем Java-коде я использую spring data jpa Pageable class,

 Pageable pageable = new PageRequest(
                    queryForm.getPageNumber()- 1, queryForm.getPageSize(),Sort.Direction.ASC,"id");  
Page page = repository.fullTextSearch(queryForm.getText(), pageable);

И я не хочу изменять структуру возврата,

Итак, когда ситуация, не связанная с страницей (поиск всех), как установить значение pageSize в MAX?

Ответ 1

В сочетании с Spring MVC вы можете использовать аннотацию PageableDefaults с value = Integer.MAX_VALUE как

public String showUsers(Model model, 
  @PageableDefaults(pageNumber = 0, value = Integer.MAX_VALUE) Pageable pageable) { … }

см. аннотацию PageableDefaults. Javadoc.

В любом другом клиентском коде вы можете установить второй параметр конструктора в Integer.MAX_VALUE:

new PageRequest(
    queryForm.getPageNumber()- 1, 
    queryForm.getPageSize() == null ? Integer.MAX_VALUE : queryForm.getPageSize(),
    Sort.Direction.ASC,"id"); 

см. конструктор PageRequest. Я предполагаю, что queryForm.getPageSize() - это тип оболочки, а не примитив. В противном случае вы получите нуль, если пользователь не задал pageSize (намеренно для запроса "поиск всего" ).

UPDATE:

Поскольку Spring Data Commons 1.6 вы должны использовать PageableDefault вместо PageableDefaults

public String showUsers(Model model, 
    @PageableDefault(page= 2 ,value = Integer.MAX_VALUE)

См. Аннотацию в PageableDefault Javadoc.

Ответ 2

Если вы используете Spring MVC, это может вам помочь. Согласно комментариям ниже, этот ответ является полностью правильным для Spring 4.xx и, возможно, более простым, но для Spring 5.xx вам, вероятно, понадобится другое решение.

Первое, что вам нужно сделать, это использовать аннотацию @PageableDefault и установить для размера значение Integer.MAX_VALUE или любое другое значение, которое вы хотите:

public SomeResponseObject getSomething(
    @PageableDefault(size = Integer.MAX_VALUE) Pageable page
) {
    return someService.getSomething(page);
}

Но это не достаточно, когда ваше значение размера очень большое (больше, чем 2000 в Spring Data CORE/пружинных данные-достоянию 1.12.3), поскольку размер будет по- прежнему ограничен maxPageSize переменной в PageableHandlerMethodArgumentResolver классе, который устанавливается по умолчанию 2000 Это было упомянуто pdorgambide. Вы получите что-то вроде этого:
Response with size limited to 2000 because of default maxPageSize
Как вы можете видеть, есть размер = 2000 вместо ожидаемого размера = 2147483647 (размер = Integer.MAX_VALUE).
Таким образом, второй шаг заключается в изменении упомянутого maxPageSize. Мы можем сделать это, переопределив PageableHandlerMethodArgumentResolver. Один из способов сделать это - создать правильный файл конфигурации Java в соответствующем пакете - если вы используете такую конфигурацию в своем проекте. Вы можете сделать это также в конфигурационном файле xml, если ваш проект использует такие. Вот мое решение (файл конфигурации Java Spring):

@Configuration
@EnableConfigurationProperties
public class PaginationConfiguration extends SpringDataWebConfiguration {

    @Bean
    public PageableHandlerMethodArgumentResolver pageableResolver() {
        PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver =
            new PageableHandlerMethodArgumentResolver(sortResolver());

        pageableHandlerMethodArgumentResolver.setMaxPageSize(Integer.MAX_VALUE);

        return pageableHandlerMethodArgumentResolver;
    }

}

Теперь все работает как положено:
Response with proper size equal to Integer.MAX_VALUE which is 2147483647

Также стоит отметить, что в аннотации @PageableDefault value равно size. Другими словами, это псевдоним для size. Это означает, что вместо size=Integer.MAX_VALUE вы можете написать value=Integer.MAX_VALUE. Более того, нет смысла использовать их одновременно. Если они различаются, учитывается только size.

Ответ 3

Если вам нужны ограничения для каждого контроллера:

@RequestMapping(path = "/users")
public ModelAndView users(@PageableLimits(maxSize = 10) Pageable pageable) {
    ...
}

@RequestMapping(path = "/comments")
public ModelAndView comments(@PageableLimits(maxSize = 100) Pageable pageable) {
    ...
}

Это можно сделать с помощью пользовательской аннотации:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface PageableLimits {
    int maxSize() default Integer.MAX_VALUE;

    int minSize() default 0;
}

И расширенная конфигурация PageableHandlerMethodArgumentResolver:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver() {

            @Override
            public Pageable resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer mavContainer,
                                            NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
                Pageable p = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
                return getLimitsFromAnnotation(p, methodParameter);
            }

            private Pageable getLimitsFromAnnotation(Pageable p, MethodParameter methodParameter) {

                PageableLimits limits = methodParameter.getParameterAnnotation(PageableLimits.class);

                if (limits == null) return p;

                if (p.getPageSize() > limits.maxSize())
                    return PageRequest.of(p.getPageNumber(), limits.maxSize(), p.getSort());
                else if (p.getPageSize() < limits.minSize())
                    return PageRequest.of(p.getPageNumber(), limits.minSize(), p.getSort());

                return p;
            }
        };

        resolver.setMaxPageSize(Integer.MAX_VALUE);
        argumentResolvers.add(resolver);
        super.addArgumentResolvers(argumentResolvers);
    }
}

Ответ 4

Вот рабочее решение для Spring 5.xx Вам просто нужно добавить конструктор по умолчанию. Смотрите приведенный выше пример:

@Configuration
public class PaginationConfiguration extends SpringDataWebConfiguration {

    /**
     * @param context           must not be {@literal null}.
     * @param conversionService must not be {@literal null}.
     */
    public PaginationConfiguration(ApplicationContext context,
                                   @Qualifier("mvcConversionService") ObjectFactory<ConversionService> conversionService) {
        super(context, conversionService);
    }

    @Bean
    public PageableHandlerMethodArgumentResolver pageableResolver() {
        PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver =
                new PageableHandlerMethodArgumentResolver(sortResolver());

        pageableHandlerMethodArgumentResolver.setMaxPageSize(Integer.MAX_VALUE);

        return pageableHandlerMethodArgumentResolver;
    }

}

Ответ 5

Это работает для меня:

Все запрашиваемые страницы используют MyCustomPage и используют страницу и размер по умолчанию, если они не найдены в запросе.

Если размер (число записей превышает максимальное значение), я устанавливаю значение по умолчанию, которое в этом случае равно 50.

public class MyCustomPage extends PageRequest{
    Integer MAX_PAGE_SIZE = 50
    //constructor 
    public MyCustomPage(Integer page, Integer size) {
        super(page,(size>MAX_PAGE_SIZE)?MAX_PAGE_SIZE:size);
    }
}

Ответ 6

Может быть, вы могли бы использовать:

@Override
@GetMapping("/some")
public ResponseEntity<Page<BaseEntityInformationDTO>> getTemplateInfo(
              @PageableDefault(sort = "displayedName") Pageable pageable, 
              @RequestParam(defaultValue = Integer.MAX_VALUE + "") Integer trueSize) {
    pageable = new PageRequest(pageable.getPageNumber, Math.max(pageable.getPageSize, trueSize),..)
    ....
}

Ответ 7

Я использую это в моем коде:

public Page<MyObject> retrieveData(@RequestBody CustomParameters query, Pageable pageable, Sort sort) {
    if (pageable == null) {
        return new PageImpl<>(repository.findAll(query.buildSpecification(), sort));
    }
    return repository.findAll(query.buildSpecification(), pageable);
}

Это имеет пару преимуществ. Если вы используете это в контроллерах, вы всегда можете определить аргументы Pageable и Sort, если запрос содержит параметр "page", Pageable будет создан автоматически (если есть параметр "sort", он будет включен в pageable, если это не нуль или в аргументе сортировки, если это так).

Вы можете настроить sortResolver и pageableResolver в своей конфигурации, и тогда у вас будет одинаковое поведение на всех ваших контроллерах.

Таким образом, когда вы отправляете запрос, вы можете указать, хотите ли вы только несколько записей (sendig - параметр "page" и "size") или хотите ли вы их все (не отправляя эти параметры), но вы всегда получаете одно и то же вернуть структуру.

Ответ 9

spring.data.rest.max-page-size=1000

используйте это свойство в application.property и назначьте более высокое значение.

Ответ 10

Для Spring 5.xx установите spring.data.rest.max-page-size=2147483647 в application.properties.