【问题标题】:JpaRepository: Spring Sort for runtime query variabelsJpa Repository:运行时查询变量的 Spring Sort
【发布时间】:2014-09-28 10:57:12
【问题描述】:

有我的普通 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 上执行这样的排序? 也许使用标准 API? 但我找不到任何例子.. 谢谢!

编辑: ok,研究了不同的方式,确信不能通过Criteria API来实现(但很可惜)

一个可行的变体:本地 SQL 查询,我确定。

【问题讨论】:

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


    【解决方案1】:

    您可以使用QueryDslPredicateExecutor 来做到这一点,它提供了以下两种方法:

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

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

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

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

    【讨论】:

      【解决方案2】:

      (抱歉目前无法评论)

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

      示例:

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

      【讨论】:

        【解决方案3】:

        Spring data jpa 确实懂order bydoc

        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"));
        

        【讨论】:

        • actual_fixed_on_top 参数如何,在运行时计算并参与 ORDER BY 子句?谢谢!
        • 是的,确实如此。查看示例findByAgeOrderByLastnameDesc() 生成find by age order by last name desc,这就是它的解析方式。
        • 其实这不是答案。
        【解决方案4】:

        我找到了解决办法:

        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...;
                    }
        
                };
            }
        }
        

        主要思想是使用案例表达式而不是简单的逻辑。 普通的 sql 等效项是:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-26
          • 2018-01-09
          • 2020-02-15
          • 2020-01-14
          • 2015-01-12
          • 2020-06-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多