在项目中想实现动态返回指定列,还有聚合查询如sum()
等,还需支持动态查询条件,看到JPA中dao继承JpaSpecificationExecutor
便可以使用List<T> findAll(@Nullable Specification<T> var1);
此方法进行查询,于是决定尝试。代码如下:
fun findArticles(data: Article, pageable: Pageable): Page<Article> {
val specific = Specification<Vacation> { root: Root<Article>, query: CriteriaQuery<*>, cb: CriteriaBuilder ->
val conditions = mutableListOf<Predicate>()
if (StringUtils.hasText(data.title)) {
val condition = cb.like(root.get("title"), "%${data.title}%")
conditions.add(condition)
}
if (data.beginDate != null) {
val condition = cb.greaterThanOrEqualTo(root.get("beginDate"), data.beginDate)
conditions.add(condition)
}
query.multiselect(
root.get<String>("title"),
root.get<String>("author")
)
query.where(*conditions.toTypedArray())
null
}
return articleDao.findAll(specific, pageable)
}
查询条件的拼装是生效的,但我只想返回title
和author
两列怎么都不行,始终是返回全部。于是跟踪源代码JpaRepositoryImplementation
的实现类SimpleJpaRepository
一路追溯,发现自定义的select
会被覆盖。
结论
JPA中Repository
就算继承JpaSpecificationExecutor
也不能实现动态拼装自定义列和聚合列的查询,复杂的查询只能使用EntityManager
构建SQL语句,简单的话可以使用@Query
或ExampleMatcher
。
issue:https://github.com/spring-projects/spring-data-jpa/issues/1842
网友评论