【问题标题】:What is the best Way to achieve Pagination with filtering in spring data jpa在spring数据jpa中过滤实现分页的最佳方法是什么
【发布时间】:2018-05-23 03:18:26
【问题描述】:

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

我通过这两种方式来实现。我正在使用弹簧数据 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()]));
    
}

公共类传输控制器 {

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

有没有其他方法可以缓解过滤和分页。请建议。 提前致谢

【问题讨论】:

  • 不要忘记接受/支持对您有帮助的答案... ;)

标签: sorting pagination spring-data-jpa


【解决方案1】:

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

我认为使用带有QueryDslWeb support 扩展的Spring Data。

首先您需要将 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 'compile' 目标...)

然后使用QueryDslPredicateExecutorQuerydslBinderCustomizer 和可选的“自定义”方法创建一个 repo(请参阅下面的“更多信息”中的详细信息):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 2012-08-06
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多