如何使用查询参数来过滤数据?
How to use query params to filter the data?
假设一个实体 Person
具有以下字段:
@Id
@GeneratedValue(startegy = GenerationType.IDENTITY)
int id;
String name;
String surname;
int age;
在控制器上,我希望可以使用查询参数自定义端点,以便它可以处理每种类型的组合:
/api/controller?name=John
/api/controller?surname=Doe
/api/controller?name=John&age=33&surname=Doe
当然,我宁愿避免手动键入所有组合。
我发现使用 @Spec
你可以定义这样的东西:
@Spec(
path = "sample",
params = { "name", "age", "surname" },
spec = //I don't know what is this
)
但这似乎并不能处理所有组合,而是我必须自己将它们组合在一起。
为每个字段定义一个规范似乎可行,但同样不能处理组合。
我错过了什么?我怎样才能做到这一点?
编辑:我发现了 QueryDSL,但我似乎无法将其导入到我的项目中。我在我的 pom 中添加了以下依赖项:
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
我正在使用 Spring 2.3.3.RELEASE
编辑:我已经修复了依赖项,但是,在启动应用程序时出现以下异常:
java.lang.IllegalArgumentException: Did not find a query class net.mydom.net.entity.QUser for domain class net.mydom.net.entity.User!
这是我的用户实体:
@Entity
@Table(name = "users")
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
@Column(name = "enterprise_id")
private String enterpriseID;
private String username;
private String name;
private String password;
private Short rol;
private Short status;
private String language;
private String email;
private Date lastLogin;
private String image;
}
如果我理解正确,您需要一种方法将 Person
中的属性映射为 API 调用中的查询参数。
建议你为此添加一个DTO应该是这样的。
public class PersonDTO {
String name;
String surname;
int age;
// constructors, getter and setters
}
现在您可以将此 DTO
作为端点方法的参数包含在内,该方法将被识别,应该是这样的:
@RestController
@RequestMapping("api/controller")
class YourController {
@GetMapping
public PersonDTO findPerson(PersonDTO personDTO) {
//the logic you want to add
return personDTO;
}
}
您可以在 PersonDTO
属性上添加带有 @Valid
注释的 javax.validation.constraints DTO 以添加一些验证。
我找到了使用 DslQuery
的解决方案
pom.xml
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</dependency>
<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/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
UserRepository.java
public interface UserRepository extends JpaRepository<User, String>,
QuerydslPredicateExecutor<User> {
}
UserController.java
@GetMapping("/dsl")
public List<User> getUserDsl( @QuerydslPredicate(root = User.class) Predicate predicate) {
return service.getUsersDsl(predicate);
}
UserService.java
public List<User> getUsersDsl(Predicate predicate) {
List<User> actualList = new ArrayList<>();
Iterable<User> iterable = repository.findAll(predicate);
iterable.forEach(actualList::add);
return actualList;
}
假设一个实体 Person
具有以下字段:
@Id
@GeneratedValue(startegy = GenerationType.IDENTITY)
int id;
String name;
String surname;
int age;
在控制器上,我希望可以使用查询参数自定义端点,以便它可以处理每种类型的组合:
/api/controller?name=John
/api/controller?surname=Doe
/api/controller?name=John&age=33&surname=Doe
当然,我宁愿避免手动键入所有组合。
我发现使用 @Spec
你可以定义这样的东西:
@Spec(
path = "sample",
params = { "name", "age", "surname" },
spec = //I don't know what is this
)
但这似乎并不能处理所有组合,而是我必须自己将它们组合在一起。 为每个字段定义一个规范似乎可行,但同样不能处理组合。
我错过了什么?我怎样才能做到这一点?
编辑:我发现了 QueryDSL,但我似乎无法将其导入到我的项目中。我在我的 pom 中添加了以下依赖项:
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
我正在使用 Spring 2.3.3.RELEASE
编辑:我已经修复了依赖项,但是,在启动应用程序时出现以下异常:
java.lang.IllegalArgumentException: Did not find a query class net.mydom.net.entity.QUser for domain class net.mydom.net.entity.User!
这是我的用户实体:
@Entity
@Table(name = "users")
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
@Column(name = "enterprise_id")
private String enterpriseID;
private String username;
private String name;
private String password;
private Short rol;
private Short status;
private String language;
private String email;
private Date lastLogin;
private String image;
}
如果我理解正确,您需要一种方法将 Person
中的属性映射为 API 调用中的查询参数。
建议你为此添加一个DTO应该是这样的。
public class PersonDTO {
String name;
String surname;
int age;
// constructors, getter and setters
}
现在您可以将此 DTO
作为端点方法的参数包含在内,该方法将被识别,应该是这样的:
@RestController
@RequestMapping("api/controller")
class YourController {
@GetMapping
public PersonDTO findPerson(PersonDTO personDTO) {
//the logic you want to add
return personDTO;
}
}
您可以在 PersonDTO
属性上添加带有 @Valid
注释的 javax.validation.constraints DTO 以添加一些验证。
我找到了使用 DslQuery
的解决方案pom.xml
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</dependency>
<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/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
UserRepository.java
public interface UserRepository extends JpaRepository<User, String>,
QuerydslPredicateExecutor<User> {
}
UserController.java
@GetMapping("/dsl")
public List<User> getUserDsl( @QuerydslPredicate(root = User.class) Predicate predicate) {
return service.getUsersDsl(predicate);
}
UserService.java
public List<User> getUsersDsl(Predicate predicate) {
List<User> actualList = new ArrayList<>();
Iterable<User> iterable = repository.findAll(predicate);
iterable.forEach(actualList::add);
return actualList;
}