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

Posted

技术标签:

【中文标题】是否可以在 Spring Boot 运行时构建自定义查询?【英文标题】:Is it possible to build customized query at run time in Spring Boot? 【发布时间】:2016-12-25 05:02:32 【问题描述】:

这就是我想要做的,

我有一个实体,

@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=""...

有没有优雅的方法来实现这个?

【问题讨论】:

方法有很多。一个好处是使用 g00glen00b 假设的标准 api。其他可能是创建自定义存储库实现并使用 jdbctemplate 根据输入参数获取结果。 【参考方案1】:

您可以使用 Spring 的规范 API,它是 JPA 标准 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)));

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

【讨论】:

【参考方案2】:

虽然不确定动态构建查询,但认为这会占用通过不同机制构建查询的时间。

Elastic Search 有助于构建此类。

一种方法是默认查询值。由于其余所有值都是枚举,因此您可以向每个枚举添加另一个枚举文字 ALL

类似的东西 Project.ALL, JobType.ALL, JobStatus.ALL。 enum 中的内部静态方法应该这样写,当查询 ALL 时,将所有 JobTypes/Project/JobStatus 添加到列表中。

可以编写一个标准查询,而不是即时构建查询。 API 甚至在缓存查询结果方面也很容易。

大多数用于搜索的 RESTful API(如 /search?project=""&amp;jobType=""&amp;jobStatus=""&amp;createTime="")都适用于默认设置。

【讨论】:

以上是关于是否可以在 Spring Boot 运行时构建自定义查询?的主要内容,如果未能解决你的问题,请参考以下文章

了解 STS:Spring Boot 应用程序在 STS 中运行良好,但使用 gradle 构建 jar 时,构建失败

带有spring-cloud的Spring Boot:gradle构建失败

子 pom 可以从自定义父 pom 的 spring-boot-starter-parent 继承插件管理和依赖管理吗?

如何在 Spring Boot 应用程序中为码头服务器自定义带有自定义正文内容的 ErrorHandler 类

Spring Boot 构建良好,但在运行时抛出 javax.naming.NameNotFoundException: remaining name: env/jmx/runtime

构建spring boot项目时出错[重复]