请求 Spring 数据 JPA 存储库时指定复杂的排序标准
Specify complex sorting criteria when requesting Spring Data JPA repository
我正在从我的数据库中请求分页和排序的数据,这些数据通过 Pageable
和以下存储库 API:
指定
org.springframework.data.jpa.repository.JpaSpecificationExecutor.findAll(Specification<MyEntity> filter, Pageable pageable)
Pageable
包含具有简单排序条件的 Sort
,例如 按降序对列 X 进行排序。
有时,Sort
包含一列实际上不存在于基础 table 中,必须用复杂的条件 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
确实,我可以在 Pageable
中重建 Sort
实例,以便删除这个不存在的列,但我没有找到注入复杂 ORDER BY
的方法在那种情况下的表达。
我试图找到一种方法来丰富此存储库调用的结果查询。我希望我可以通过添加另一个 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);
我不想放弃利用 Spring 数据 findAll(filter, pageable)
的当前实现。我只想在一种情况下 丰富 它。怎么做到的?
对于这种情况,您可以使用自定义 SQL 在 MyEntity
中创建 @Formula
列,然后在 Pageable
中将其作为常规实体字段引用
我正在从我的数据库中请求分页和排序的数据,这些数据通过 Pageable
和以下存储库 API:
org.springframework.data.jpa.repository.JpaSpecificationExecutor.findAll(Specification<MyEntity> filter, Pageable pageable)
Pageable
包含具有简单排序条件的 Sort
,例如 按降序对列 X 进行排序。
有时,Sort
包含一列实际上不存在于基础 table 中,必须用复杂的条件 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
确实,我可以在 Pageable
中重建 Sort
实例,以便删除这个不存在的列,但我没有找到注入复杂 ORDER BY
的方法在那种情况下的表达。
我试图找到一种方法来丰富此存储库调用的结果查询。我希望我可以通过添加另一个 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);
我不想放弃利用 Spring 数据 findAll(filter, pageable)
的当前实现。我只想在一种情况下 丰富 它。怎么做到的?
对于这种情况,您可以使用自定义 SQL 在 MyEntity
中创建 @Formula
列,然后在 Pageable
中将其作为常规实体字段引用