Как я могу преобразовать сортировку данных Spring в OrderSpecifier querydsl?

Это в основном противоположно этому: Как сделать постраничный запрос QueryDSL с помощью Spring JPA?

Это для пользовательского запроса, для которого я не могу использовать ни один из методов findAll().

РЕДАКТИРОВАТЬ:

Вставил неправильную ссылку. Сейчас исправлено.


person beginner_    schedule 25.10.2012    source источник


Ответы (5)


Вы можете сделать что-то вроде этого: но обязательно обрежьте o.getProperty(), чтобы вы передавали только свойство, а не псевдоним. + свойство

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())));
    }
}
person Frank    schedule 27.10.2012
comment
помечен как ответ, поскольку на мой вопрос был дан ответ, и я пришел к тому же решению, за исключением использования MyClass.class вместо Object.class. Однако как мне сделать это общим способом, например, MyClass на самом деле ‹T extends MyClass›? - person beginner_; 27.10.2012
comment
Вы должны повторно использовать orderByExpression, так как это общий родитель для порядка по дочерним элементам. Также название вводит в заблуждение, так как дочерние элементы являются фактическим порядком выражений. - person Timo Westkämper; 29.10.2012
comment
Этот вид работает для моего случая, но не полностью. Проблема в том, что мне нужно отсортировать вычисляемые поля (сумма, количество). У меня они есть как псевдонимы, но проблема в том, что PathBuilder всегда добавляется к псевдониму запроса. + имущество. В примере он всегда возвращает ORDER BY object.{alias}, который недействителен. Как я могу заставить QueryDSL просто добавить ORDER BY {alias}? - person Cenobyte321; 06.09.2016
comment
Это сработало для меня после некоторой возни. Кто-нибудь знает, безопасно ли это? - person wmakley; 02.07.2020
comment
согласен - работает отлично - person Matley; 25.12.2020

Я не знаю, актуально ли это, но в jpa данных Spring есть реализация для преобразования между объектом data.domain.Sort (Spring JPA) и OrderSpecifier (QueryDSL).

Поддержка GIT-источника Querydsl в Spring JPA

Это действительно уродливая реализация, но вы все равно можете повторно использовать ее для своих целей, поскольку метод является закрытым:

public JPQLQuery applySorting(Sort sort, JPQLQuery query)

Но если вы используете Spring data JPA в своей пользовательской реализации репозитория, вам просто нужно сделать:

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

Надеюсь, это могло помочь!

person Community    schedule 03.03.2014

org.springframework.data.domain.Sort.Order и com.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));
}
person Dario    schedule 25.11.2017

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()))
person Junyeong Yeo    schedule 27.11.2020
comment
Что такое objectDTO? - person Marinos An; 23.12.2020
comment
Это означает новый экземпляр, сгенерированный Querydsl. - person Junyeong Yeo; 31.12.2020

В качестве альтернативы, если вы хотите напрямую применить сортировку к базовому запросу без необходимости преобразования в 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);
person sha-mik    schedule 10.02.2021
comment
Сообщество рекомендует добавлять пояснения к коду, а не просто ответы, основанные на коде (см. только ответы">здесь). - person costaparas; 10.02.2021