【发布时间】:2020-09-02 13:08:36
【问题描述】:
如何通过聚合嵌套属性实现排序对象? 我有一个摄影师实体,其中一个有很多带有名为 pricePerHour 的 BigDecimal 属性的摄影师价格实体(一对多)。当我检索摄影师时,我想按照他们的最低价格对他们进行排序。
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Photographer> cq = cb.createQuery(Photographer.class);
Root<Photographer> root = cq.from(Photographer.class);
List<Predicate> predicates = new ArrayList<>(); // I have a lot of predicates which set if data was present by client
我尝试对摄影师价格进行子查询,然后在根目录中进行排序
Subquery<BigDecimal> subquery = cq.subquery(BigDecimal.class);
Root<PhotographerPrice> from = subquery.from(PhotographerPrice.class);
Predicate and = cb.and(
cb.equal(root.get(Photographer_.id), from.get(PhotographerPrice_.photographer).get(Photographer_.id)),
cb.isNotNull(from.get(PhotographerPrice_.pricePerHour))
);
subquery.correlate(root);
subquery.where(and);
subquery.select(cb.min(from.get(PhotographerPrice_.pricePerHour)));
subquery.groupBy(from.get(PhotographerPrice_.photographer).get(Photographer_.id));
...
cq.orderBy(cb.asc(subquery));
但是,我意识到,不允许在 order by 子句中使用子查询。
那么,我如何使用 Criteria API 实现这样的功能:
select *
from photographer p
order by (
select min(price_per_hour) minPrice
from photographer_price pp
where p.id = pp.photographer_id
and pp.photo_per_hour is not null
group by photographer_id
);
当我尝试使用 Join 方法实现它时,我的结果列表中有重复项。
是否可以使用 Criteria API 来实现它?也许还有另一种工具可以更方便地过滤来自 DB 的实体?我有很多不同的参数用于过滤和排序,这些参数与嵌套属性有关,有时甚至与嵌套在嵌套属性中有关。
我找到解决它的唯一方法:
ListJoin<Photographer, PhotographerPrice> join = root.join(Photographer_.photographerPrices);
Expression<BigDecimal> min = cb.min(join.get(PhotographerPrice_.pricePerHour));
cq.orderBy(cb.desc(min));
cq.groupBy(root.get(Photographer_.id));
但我不确定分组依据。以后会不会出现一些故障排除?
【问题讨论】:
标签: java spring hibernate spring-data-jpa criteria-api