如何将 spring 数据排序转换为 querydsl OrderSpecifier?
Posted
技术标签:
【中文标题】如何将 spring 数据排序转换为 querydsl OrderSpecifier?【英文标题】:How can I convert a spring data Sort to a querydsl OrderSpecifier? 【发布时间】:2012-10-15 20:38:56 【问题描述】:这基本上与此相反: How to do a paged QueryDSL query with Spring JPA?
这是针对我无法使用任何 findAll() 方法的自定义查询。
编辑:
发错链接了。现在更正了。
【问题讨论】:
【参考方案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 实际上是我不知道它是否仍然相关,但在 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.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));
【讨论】:
【参考方案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)。以上是关于如何将 spring 数据排序转换为 querydsl OrderSpecifier?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用弹簧数据将 BigInteger 转换为 Objectid
将 CSV 读入 Spring Boot 应用程序时,如何将数据表列从累积转换为差异?