是否可以在Spring Boot中运行时构建自定义查询?

时间:2016-08-18 10:00:08

标签: java spring rest spring-boot spring-data-jpa

这就是我想要做的,

我有一个实体,

@Entity
public class JobEntity {

    @Id
    @GeneratedValue
    private Long id;

    @Enumerated(EnumType.STRING)
    private Project project;

    @Enumerated(EnumType.STRING)
    private JobType jobType;

    @Enumerated(EnumType.STRING)
    private JobStatus jobStatus;

    private Date createTime;
}

我知道我可以在存储库中自定义一个查询,但这只是一个固定的查询。我希望导出一些RESTful api,如下所示,

/search?project=""&jobType=""&jobStatue=""&createTime=""

这些参数不应该强制要求,并且可以轻松地使用它们中的任何一个进行查询,例如

/search?createTime=""...

有没有一种优雅的方式来实现它?

2 个答案:

答案 0 :(得分:2)

您可以使用Spring的规范API,它是JPA criteria API的包装器。确保您的存储库从JpaSpecificationExecutor<JobEntity>

延伸

示例规范将是:

public class JobEntitySpecifications {
    public static Specification<JobEntity> withProject(Project project) {
        if (project == null) {
            return null;
        } else {
            return (root, query, cb) -> cb.equal(root.get("project"), project);
        }
    }

    public static Specification<JobEntity> withJobType() { ... }
    public static Specification<JobEntity> withJobStatus() { ... }
    public static Specification<JobEntity> withCreateTime() { ... }
}

确保在没有给出项目代码/作业类型/ ...时返回null,以便在查询中忽略它。

现在你可以使用它:

repository.findAll(Specifications.where(JobEntitySpecifications.withJobType(jobType))
    .and(JobEntitySpecifications.withJobStatus(jobStatus))
    .and(JobEntitySpecifications.withProject(project))
    .and(JobEntitySpecifications.withCreateTime(createTime)));

如果你在这里使用静态导入,你可以让它看起来更好。

答案 1 :(得分:0)

虽然不确定是否动态构建查询,但认为这会耗费时间来通过不同的机制构建查询。

Elastic Search有助于构建这样的内容。

其中一种方法是默认查询值。所有值的其余部分都是枚举,您可以将每个枚举的另一个枚举文字添加为ALL

等等 Project.ALL, JobType.ALL, JobStatus.ALL。枚举中的内部静态方法应该这样写,当查询ALL时,然后将所有JobTypes / Project / JobStatus添加到列表中。

可以编写单个标准查询,而不是动态构建查询。在缓存查询结果方面,API很容易。

大多数用于搜索的RESTful API(例如/search?project=""&jobType=""&jobStatus=""&createTime=""用于默认。