如何使用查询参数来过滤数据?

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