JpaRepository:Spring为运行时查询变量排序

时间:2014-08-05 17:11:49

标签: sql hibernate sorting jpa spring-data-jpa

有我的普通sql查询:

SELECT id, title, 
IF(o.fixed_on_top = 1 AND o.fixing_on_top_day_counter > 5, 1 ,0) actual_fixed_on_top 
FROM orders o
ORDER BY actual_fixed_on_top DESC, publication_date DESC;

如何在JpaRepository上执行这样的排序? 也许使用Criteria API? 但我发现任何例子...... 谢谢!

编辑: 好的,研究了不同的方法,并确信它不能通过Criteria API实现(但很可惜)

一个工作变体:Native SQL Query,我相信。

4 个答案:

答案 0 :(得分:1)

您可以使用提供以下两种方法的QueryDslPredicateExecutor来完成此操作:

Iterable<T> findAll(Predicate predicate, OrderSpecifier<?> ... orderSpecifiers);

Page<T> findAll(Predicate predicate, Pageable pageable);

PageRequest类实现Pageable并允许您指定所需的排序。

您还可以在常规Pageable上的@Query注释方法中添加JpaRepository参数,Spring Data Jpa将完成其余工作,例如:

@Query("select e from SomeEntity e where e.param1 = :param1")
public Page<SomeEntity> findSome(@Param("param1") String param1, Pageable pageable);

答案 1 :(得分:0)

(抱歉还不能发表评论)

我最近遇到了同样的问题。 对我有用的唯一解决方案是指定关系的顺序。 我在查询中看不到关系

示例:

@OneToMany
@OrderBy("date")
...

答案 2 :(得分:0)

Spring数据jpa确实理解order by,请参阅doc

findByAgeOrderByLastnameDesc()将被解析为where x.age = ?1 order by x.lastname desc子句。

我认为您的案例有点复杂,但您可以使用@Query注释执行JQPL,示例:

@Query("SELECT o FROM Order o WHERE write your clause ORDER BY o.something desc")
public Order findByCustomPK(@Param("paramIfNeeded"));

答案 3 :(得分:0)

我找到了解决方案:

public class MyEntitySpecifications {

    public static Specification<MyEntity> GetByPageSpecification() {
        return new Specification<MyEntity>() {

            @Override
            public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                Expression fixingExpr = cb.greaterThan(root.get(MyEntity_.fixingDueDate), new DateTime(DateTimeZone.UTC));
                cq.orderBy(new OrderImpl(cb.selectCase().when(fixingExpr, 1).otherwise(0), false));

                return cb...;
            }

        };
    }
}

主要思想是使用case表达式而不是简单的逻辑。 plain sql equuivalent是:

select ...
from my_entity e
where ...
order by case when e.fixing_due_date > now() then 1 else 0 end desc

因此我们也可以使用标准api规范构建动态查询。 没有直接访问EntityManager,没有普通的sql。