是否可以在 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=""&jobType=""&jobStatus=""&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