【问题标题】:How can I convert a spring data Sort to a querydsl OrderSpecifier?如何将 spring 数据排序转换为 querydsl OrderSpecifier?
【发布时间】:2012-10-15 20:38:56
【问题描述】:

这基本上与此相反: How to do a paged QueryDSL query with Spring JPA?

这是针对我无法使用任何 findAll() 方法的自定义查询。

编辑:

发错链接了。现在更正了。

【问题讨论】:

    标签: spring-data querydsl


    【解决方案1】:

    您可以这样做:但请确保修剪 o.getProperty(),以便您只传递属性而不是“别名”。+property

    if (pageable != null) {
        query.offset(pageable.getOffset());
        query.limit(pageable.getPageSize());
        for (Sort.Order o : pageable.getSort()) {
            PathBuilder<Object> orderByExpression = new PathBuilder<Object>(Object.class, "object");
    
            query.orderBy(new OrderSpecifier(o.isAscending() ? com.mysema.query.types.Order.ASC
                    : com.mysema.query.types.Order.DESC, orderByExpression.get(o.getProperty())));
        }
    }
    

    【讨论】:

    • 标记为答案,因为我的问题得到了回答,我得到了相同的解决方案,除了使用 MyClass.class 而不是 Object.class。但是我如何以通用方式执行此操作,例如 MyClass 实际上是 ?
    • 您应该重用 orderByExpression,因为它是子订单的共同父代。这个名字也有误导性,因为孩子是真正的“按表达式排序”。
    • 这种适用于我的情况,但不完全。问题是我需要对计算字段(总和、计数)进行排序。我将它们作为别名,但问题是 PathBuilder 总是附加到查询“别名”。 + 财产。在示例中,它始终返回无效的“ORDER BY object.{alias}”。如何让 QueryDSL 只附加“ORDER BY {alias}”?
    • 经过一番摆弄后,这对我有用。有人知道它是否安全吗?
    【解决方案2】:

    我不知道它是否仍然相关,但在 spring data jpa 中有一个实现,用于在 data.domain.Sort (Spring JPA) 对象到 OrderSpecifier (QueryDSL) 之间进行转换。

    GIT Source of Querydsl Support in Spring JPA

    这是一个非常丑陋的实现,但由于方法是私有的,您仍然可以将其重用于自己的目的:

    public JPQLQuery applySorting(Sort sort, JPQLQuery query)
    

    但是如果你使用 Spring data JPA,在你的自定义 Repository 实现中,你只需要这样做:

    public Page<MyObject> findAll(Predicate predicate, Pageable pageable) {
    
        QMyObject myObject = QMyObject.myObject;
        JPQLQuery jPQLQuery = from(myObject)
                .join(myObject.user)
                .where(predicate);
        jPQLQuery = getQuerydsl().applyPagination(pageable, jPQLQuery);
        List<MyObject> myObjectList = jPQLQuery.list(myObject);
        long count =  jPQLQuery.count();
        Page<MyObject> myObjectPage = new PageImpl<MyObject>(myObjectList, pageable, count);
        return myObjectPage;  
    }
    

    希望对您有所帮助!

    【讨论】:

      【解决方案3】:

      org.springframework.data.domain.Sort.Ordercom.querydsl.core.types.Order 非常相似,但两者之间没有直接的转换。这是frozenfury 的改进版本@ 答案:

      PathBuilder<Entity> entityPath = new PathBuilder<>(Entity.class, "entity");
      for (Order order : pageable.getSort()) {
          PathBuilder<Object> path = entityPath.get(order.getProperty());
          query.orderBy(new OrderSpecifier(com.querydsl.core.types.Order.valueOf(order.getDirection().name()), path));
      }
      

      【讨论】:

        【解决方案4】:
        private OrderSpecifier<?>[] getSortedColumn(Sort sorts){   
            return sorts.toList().stream().map(x ->{
                Order order = x.getDirection().name() == "ASC"? Order.ASC : Order.DESC;
                SimplePath<Object> filedPath = Expressions.path(Object.class, Qobject, x.getProperty());
                return new OrderSpecifier(order, filedPath);
            }).toArray(OrderSpecifier[]::new);
        }
        

        那么你可以这样使用:

          .where(...), 
          .orderBy(getSortedColumn(pageable.getSort()))
        

        【讨论】:

        • 什么是objectDTO
        • 表示Querydsl生成的新Instance。
        【解决方案5】:

        或者,如果您想直接将排序应用到基本查询中而无需转换为 OrderSpecifier>,您可以利用 org.springframework.data.jpa.repository.support.Querydsl

        JPQLQuery<?> query = new JPAQuery<>(entityManager);
        //prepare your base query
        query.select(<YourQEntity>).from(<YourQEntity>).where(<whereClause>);
        
        Querydsl querydsl = new Querydsl(entityManager, (new PathBuilderFactory()).create(<YourEntityClass>.class));
        
        //apply org.springframework.data.domain.Sort
        querydsl.applySorting(pageable.getSort(), query);
        

        【讨论】:

        • 社区鼓励在代码中添加解释,而不是纯粹基于代码的答案(参见here)。
        猜你喜欢
        • 2016-10-10
        • 1970-01-01
        • 2014-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多