在spring data jpa中使用过滤实现分页的最佳方法是什么

时间:2017-12-08 20:35:30

标签: sorting pagination spring-data-jpa

我正在尝试在服务器端实现分页以及过滤器。

我实现了这两种方式。我正在使用spring data jpa。

1.使用JpaSpecificationExecutor编写规范

2.使用QueryDslPredicateExecutor并使用QueryDSL编写谓词。

我从 JpaSpecificationExecutor 开始,但发现它很复杂。

这是我的规范类:

公共类TransmissionSearchSpecification实现规范{

 private TransmissionSearch criteria;

 public TransmissionSearchSpecification(TransmissionSearch ts) {
        criteria= ts;
    }

@Override
public Predicate toPredicate(Root<TransmissionView> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) {
    Path<String> thirdParty = root.get(TransmissionView_.thirdPartyName);

     final List<Predicate> predicates = new ArrayList<Predicate>();
        if(criteria.getThirdPartyName() !=null) {
            predicates.add(builder.equal(thirdParty, criteria.getThirdPartyName()));
        }

        return builder.and(predicates.toArray(new Predicate[predicates.size()]));

}

public class TransmissionController {

private final TransmissionViewService transmissionViewService; 

public  TransmissionController(TransmissionViewService transmissionViewService) {
    this.transmissionViewService = transmissionViewService;

}

@RequestMapping("/transmissions/search")
@GetMapping
public ResponseEntity<Page<TransmissionView>> getTransmissions(TransmissionSearch transmissionSearch, Pageable pageable){
    Page<TransmissionView> transmissions = transmissionViewService.findTransmissions(pageable);
    if(!CollectionUtils.isEmpty(transmissions.getContent())) {
        return new ResponseEntity<>(transmissions, HttpStatus.OK);
    } else {
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
}

还有其他方法可以减轻过滤器和分页。请建议。 提前致谢

1 个答案:

答案 0 :(得分:0)

  

在弹簧数据jpa中使用过滤实现分页的最佳方法是什么?

我认为将Spring数据用于QueryDslWeb support扩展名。

首先,您需要将 QueryDsl 插入项目:

<dependencies>
    //...
    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
        <version>${querydsl.version}</version>
    </dependency>

    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <version>${querydsl.version}</version>
    </dependency>

</dependencies>
<build>
    <plugins>
        //...
        <plugin>
            <groupId>com.mysema.maven</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <version>1.1.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>target/generated-sources/annotations</outputDirectory>
                        <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

(别忘了执行maven&#39;编译&#39;目标......)

然后创建一个包含QueryDslPredicateExecutorQuerydslBinderCustomizer和可选&#39;自定义&#39;方法(详情请见&#39;更多信息&#39;):

public interface TransmissionRepo extends JpaRepository<Transmission, Long>, QueryDslPredicateExecutor<Transmission>, QuerydslBinderCustomizer<Transmission> {

  @Override
  default void customize(QuerydslBindings bindings, QTransmission transmission) {

    bindings.excluding( 
        // excluding some fields from filter 
        transmission.id,
        transmission.version
    );

    // implement ignore case to strings...
    bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::containsIgnoreCase);

    // https://stackoverflow.com/a/35158320/5380322
    // 'between' implementation - if you need this...
    bindings.bind(listing.createdOn).all((path, value) -> {

      Iterator<? extends LocalDate> it = value.iterator();
      LocalDate from = it.next();
      if (value.size() >= 2) {
        LocalDate to = it.next();
        return path.between(from, to);
      } else {
        return path.eq(from);
      }
    });
  }
}

然后,如果您在项目中使用 Spring Data REST ,则可以使用过滤器以及分页:

GET /transmissions?page=1&size=10&sort=field1,desc&field2=value2&field3=value3

或者您可以实现自定义控制器,例如:

@GetMapping("/transmissions")
@ResponseBody
public Iterable<Transmission> findAll(@QuerydslPredicate(root = Transmission.class) Predicate predicate, Pageable pageable) {
    return TransmissionRepo.findAll(predicate, pageable);
}

根据您的问题,您可以找到更多信息here