小编典典

如何使用Querydsl和Spring Data轻松实现“ REST API查询语言”以过滤实体?

spring-boot

如何使用 Spring Data 轻松实现一种“ REST API查询语言” 以过滤实体?

例如,对于以下Person实体:

@Data
@Entity
public class Person {

  @Id
  @GeneratedValue
  private Long id;

  private LocalDate dob; // date of birth

  private String name;

  @Formula("timestampdiff('year', dob, now())")
  private Integer age;

  public Person(String name, LocalDate dob) {
    this.name = name;
    this.dob = dob;
  }
}

我想通过这样的请求获取其数据:

GET /people?name=jo&age=18&page=1&sort=name,desc

即:“获取所有name包含“ jo”(不区分大小写)且age等于18的人的第一页,name以降序排列。


阅读 473

收藏
2020-05-30

共1个答案

小编典典

借助Querydsl Web支持Web支持Spring数据扩展)的一部分,我们可以轻松实现一种“ REST
API查询语言”来过滤我们的实体。

我们需要做的是:

1)扩大我们的资料库QuerydslPredicateExecutor

2)将Predicate带有注释的@QuerydslPredicate参数添加到我们的REST控制器方法中

3)findAll在存储库的方法中使用此谓词:

public interface PersonRepo extends JpaRepository<Person, Long>, QuerydslPredicateExecutor<Person> {
}



@RequiredArgsConstructor
@RestController
@RequestMapping("/people")
public class PersonController {

    private final PersonRepo personRepo;

    @GetMapping
    public ResponseEntity getFiltered(@QuerydslPredicate(root = Person.class) Predicate predicate, Pageable pageable) {
        return ResponseEntity.ok(personRepo.findAll(predicate, pageable)));
    }
}

然后,我们将能够请求我们的数据:

GET /people?name=John&age=18&page=1&sort=name,desc

接下来,我们必须创建不区分大小写的“
like”过滤器。为此,我们从扩展仓库QuerydslBinderCustomizer并覆盖其customize方法(在仓库中):

public interface PersonRepo extends
        JpaRepository<Person, Long>,
        QuerydslPredicateExecutor<Person>,
        QuerydslBinderCustomizer<QPerson> {

    @Override
    default void customize(QuerydslBindings bindings, QPerson person) {

        // Make case-insensitive 'like' filter for all string properties 
        bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::containsIgnoreCase);
    }
}

为了使我们的作品有参数添加bindings@QuerydslPredicate我们的控制器的方法:

@GetMapping
public ResponseEntity getFiltered(
    @QuerydslPredicate(root = Person.class, bindings = PersonRepo.class) Predicate predicate, 
    Pageable pageable
) {
    return ResponseEntity.ok(personRepo.findAll(predicate, pageable)));
}

现在,我们可以按照问题中的要求获取数据:

GET /people?name=jo&age=18&page=1&sort=name,desc

使用QuerydslBinderCustomizer我们可以实现更复杂的过滤器,例如betweengreater or equal过滤器(将此代码添加到customize方法中):

bindings.bind(person.age).all((path, value) -> {
    Iterator<? extends Integer> it = value.iterator();
    Integer from = it.next();
    if (value.size() >= 2) {
        Integer to = it.next();
        return Optional.of(path.between(from, to)); // between
    } else {
        return Optional.of(path.goe(from)); // greater or equal
    }
});

如果我们age在请求中指定了两个参数,那么我们将获得所有记录,这些记录的年龄 介于 这些参数 之间 。如果仅指定一个age参数-
我们将获得年龄大于或等于该值的记录。

GET /people?age=18&age=30

让所有年龄在18至30岁之间的人

GET /people?age=18

让所有年龄大于或等于18岁的人

最后,我们可以从过滤器中排除一些不必要的属性,例如实体id(将此代码添加到customize方法中):

bindings.excluding(person.id);

要使用Querydsl Web支持,我们必须将以下依赖项和插件添加到我们的Spring Boot项目中:

<dependencies>
    <!-- ... -->

    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <scope>provided</scope>
    </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>

然后,重要的是, 编译项目 以构建我们实体的“ Q类”。

您可以在我的仓库中找到完整的示例演示:sb-
querydsl-sd-demo
和该演示的Postman API文档-在这里:带有Querydsl和Spring
Data的REST查询语言

2020-05-30