如何将Spring Data中的Sort转换为Querydsl中的OrderSpecifier?

19
5个回答

22
你可以像这样做:但一定要修剪 o.getProperty(),以便仅传递属性而不是 "alias." + 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 实际上是 <T extends MyClass>? - beginner_
1
你应该重复使用orderByExpression,因为它是order by子句的常见父级。此外,名称有误导性,因为子级才是实际的“order by表达式”。 - Timo Westkämper
1
这对我的情况有些作用,但并不完全适用。问题在于我需要对计算字段(sum、count)进行排序。我将它们作为别名,但问题是 PathBuilder 总是将查询附加到“alias.”+属性。例如,它总是返回“ORDER BY object.{alias}”,这是无效的。我该如何让 QueryDSL 只附加“ORDER BY {alias}”? - Cenobyte321
在一些调试后,这对我起作用了。有人知道它是否安全吗? - wmakley

9

我不知道这是否仍然相关,但在Spring Data JPA中有一种实现可以将data.domain.Sort(Spring JPA)对象转换为OrderSpecifier(QueryDSL)。

Spring JPA中Querydsl支持的GIT源代码

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

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

希望它能有所帮助!


5
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 是什么? - Marinos An
它的意思是由Querydsl生成的新实例。 - Junyeong Yeo
正是我所需要的。太棒了,解决方案非常出色。 - Thalys Menezes

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

0

或者,如果您想直接将排序应用于基本查询而无需转换为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);

社区鼓励在代码旁边添加解释,而不是仅仅提供基于代码的答案(请参见此处)。 - costaparas
最佳答案!它就是有效的(2023年5月) - liy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接