[英]Specify complex sorting criteria when requesting Spring Data JPA repository
I'm requesting paged and sorted data from my database, specified via Pageable
with following repository API:我正在从我的数据库中请求分页和排序的数据,这些数据是通过
Pageable
指定的,带有以下存储库 API:
org.springframework.data.jpa.repository.JpaSpecificationExecutor.findAll(Specification<MyEntity> filter, Pageable pageable)
Pageable
contains a Sort
with simple sorting criteria, such as sort column X in descending order . Pageable
包含一个具有简单排序条件的Sort
,例如对 X 列进行降序排序。
Sometimes, Sort
contains one column which actually doesn't exist in the underlying table, which must be replaced by a complex conditional ORDER BY
expression:有时,
Sort
包含一个在基础表中实际上不存在的列,必须用复杂的条件ORDER BY
表达式替换:
ORDER BY CASE WHEN entity_to='CUSTOMER' THEN entity_to_id ELSE (CASE WHEN entity_from='CUSTOMER' THEN entity_from_id END) END
Indeed, I can rebuild the Sort
instance in Pageable
so that this non-existing column gets removed, but I didn't find a way to inject the complex ORDER BY
expression in that case.实际上,我可以在
Pageable
中重建Sort
实例,以便删除这个不存在的列,但在这种情况下我没有找到注入复杂ORDER BY
表达式的方法。
I tried to find a way, to enrich the resulting query from this invocation of the Repository.我试图找到一种方法来丰富来自此存储库调用的结果查询。 I hoped that I can do it by adding another
Specification
filter, but I got an error ( No explicit selection and an implicit one could not be determined
), and I'm not sure that the order-by will be applied to the final query built by the Repository implementation:我希望我可以通过添加另一个
Specification
过滤器来做到这一点,但是我得到了一个错误( No explicit selection and an implicit one could not be determined
),而且我不确定 order-by 是否会应用于最终查询由存储库实现构建:
...
filter = filter.and(
(root, query, cb) -> {
final var customerLiteral = cb.literal("CUSTOMER");
final var caseExpression = cb.selectCase(root.get(MyEntity_.ENTITY_TO))
.when(customerLiteral, root.get(MyEntity_.ENTITY_TO_ID)).otherwise(
cb.selectCase(root.get(MyEntity_.ENTITY_FROM))
.when(customerLiteral, root.get(MyEntity_.ENTITY_FROM_ID)).otherwise(0));
final var order = ascElseDesc ? cb.asc(caseExpression) : cb.desc(caseExpression);
final var cq = cb.createQuery(MyEntity.class);
return cb.exists(cq.select(root).orderBy(order).subquery(MyEntity.class));
}
);
repository.findAll(filter, pageable);
I don't want to drop the current implementation which leverages Spring Data's findAll(filter, pageable)
.我不想放弃利用 Spring Data 的
findAll(filter, pageable)
的当前实现。 I only would like to enrich it in one case.我只想在一种情况下丰富它。 How can it be done?
怎么做到呢?
对于这种情况,您可以使用自定义 SQL 在MyEntity
中创建@Formula
列,然后在Pageable
中将其作为常规实体字段引用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.