Spring ...

Select/Multiselect在JPA的Specifica

2021-07-04  本文已影响0人  Anson_1f2a

在项目中想实现动态返回指定列,还有聚合查询如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)
    }

查询条件的拼装是生效的,但我只想返回titleauthor两列怎么都不行,始终是返回全部。于是跟踪源代码JpaRepositoryImplementation的实现类SimpleJpaRepository一路追溯,发现自定义的select会被覆盖。

image.png

结论

JPA中Repository就算继承JpaSpecificationExecutor也不能实现动态拼装自定义列和聚合列的查询,复杂的查询只能使用EntityManager构建SQL语句,简单的话可以使用@QueryExampleMatcher
issue:https://github.com/spring-projects/spring-data-jpa/issues/1842

上一篇下一篇

猜你喜欢

热点阅读