如何使用Spring Data轻松实现一种“REST API查询语言”来过滤实体?
例如,对于以下个人
实体:
@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
即:“获取< code>name包含“jo”(不区分大小写)且< code>age等于18的所有人的第一页,按< code>name降序排序”。
借助Querydsl Web Support,Web支持Spring Data扩展的部分,我们可以轻松实现一种“REST API查询语言”来过滤我们的实体。
我们所需要的只是执行以下操作:
1)从QuerydslPredicateExecitor
扩展我们的存储库,
2)将带有注释@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
扩展我们的存储库并覆盖其自定义
方法(就在存储库中):
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);
}
}
为了使它工作,我们必须添加参数< code>bindings到我们的控制器方法的< code>@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
通过< code > QuerydslBinderCustomizer ,我们可以实现更复杂的过滤器,例如< code>between和< code>greater or equal过滤器(将此代码添加到< code>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
(将此代码添加到自定义
方法):
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-docs - 这里:REST查询语言与Querydsl和Spring Data。
如何使用Graphql SPQR实现查询过滤器和排序? 我正在寻找一个解决方案,用Graphql SPQR的模式看起来像这样。
我有一个这样的实体层次结构。除了一些常见属性外,一些属性仅由少数子类型共享: 使用QueryDSL,我试图根据动态筛选标准搜索人员,如: 这似乎不是正确的方式,然而,我得到了很多错误,比如“薪水”不是一个人的成员。 处理层次实体搜索的各种方法有哪些?为了类型安全,我更喜欢QueryDSL,但使用Spring数据规范的解决方案也可以。 编辑:使用15种不同的搜索标准,搜索标准可能会变得非常复杂。所以
本文向大家介绍利用JS轻松实现获取表单数据,包括了利用JS轻松实现获取表单数据的使用技巧和注意事项,需要的朋友参考一下 接触过Angularjs的都知道,ng支持双向绑定,我们可以轻轻松松的通过ngModel将我们的值绑定到界面,当修改了值提交表单的时候不需要再重新通过ID去重新抓取输入框信息了。那对于我们开发前台网站,不用ng一类的MVVM框架,只引用了Jquery,那么在处理表单的时候该怎么做
我使用Spring批处理和Spring数据(以及Hibernate)在数据库表中插入CSV文件。每次插入CSV时,我都必须使用data jpa deleteAll()方法删除表中以前的数据。问题在于,在每个delete/insert语句之后,表的ID都会自动连续递增(@GeneratedValue(strategy=GenerationType.IDENTITY))。我希望每次删除后,ID从1开始
本文向大家介绍轻松实现Android语音识别功能,包括了轻松实现Android语音识别功能的使用技巧和注意事项,需要的朋友参考一下 苹果的iphone有语音识别用的是Google的技术,做为Google力推的Android 自然会将其核心技术往Android 系统里面植入,并结合google 的云端技术将其发扬光大。 所以Google Voice Recognition在Android 的实现就变