如何使用Spring JPA进行QueryDSL分页查询?

7
QueryDSL定义了一个OrderSpecifier接口,可以通过调用asc()或desc()轻松地为任何字段获取实例。Spring Data JPA的QueryDslPredicateExecutor接口甚至有一个findAll()方法,它以OrderSpecifier作为参数。
然而,org.springframework.data.domain.PageRequest并不知道QueryDSL,它有自己的定义查询排序顺序的方式,即org.springframework.data.domain.Sort。它可以包含许多类似于OrderSpecifier的org.springframework.data.domain.Sort.Order,但它们不是类型安全的等等。
因此,如果我想进行分页查询并使用排序,真的没有办法使用QueryDSL来定义吗?
4个回答

9

我知道已经有一段时间了,不确定在OP发布时是否可用,但现在有一个新的QPageRequest对象,它允许通过QueryDSL进行排序并添加到Spring Data JPA Query DSL中...


8

以下是一个使用QueryDSL构建Sort对象的更简单方法:

new QSort(user.manager.firstname.asc())

然后你可以像这样在 PageRequest 中使用它:
new PageRequest(0, 10, new QSort(user.manager.firstname.asc()))

6
如果找不到其他方法,它应该像这样工作。
private Sort sortBy(Path<?> path) {
    return new Sort(Sort.Direction.ASC, path.getMetadata().getExpression().toString());
}

谢谢。有点丑,但比使用硬编码的表达式名称要好得多。你能否添加缺失的括号,以便其他人可以复制粘贴您的评论而不需要修改它。 - eh.
getExpression() 似乎已被移除,目前没有简单的方法可以获取整个表达式名称,只能使用 getName() 获取最后一个元素的名称。 - EpicPandaForce
整个序列化的表达式是 path.toString(),但它还包含了根变量的名称。 - Timo Westkämper

1
“getExpression()”方法已被删除,我有类似于“QPost.post.period.periCode”的表达式需要遍历,但是由于没有完整的表达式名称,我无法对其进行任何操作。因此,现在我创建了一个方法来收集“period.periCode”,并且在“QPost.post”上运行得非常完美。请注意保留HTML标签。
private String resolveOrderPath(Path<?> path) {
    StringBuilder stringBuffer = new StringBuilder(path.getMetadata().getName());
    path = path.getMetadata().getParent();
    while(!path.getMetadata().isRoot()) {
        stringBuffer.insert(0, path.getMetadata().getName() + ".");
        path = path.getMetadata().getParent();
    }
    return stringBuffer.toString();
}

Path<?> path = QPost.post.period.periCode;
String propertyPath = resolveOrderPath(path);
Sort sort = new Sort("asc".equals(sSortDir0) ? Sort.Direction.ASC : Sort.Direction.DESC, propertyPath);

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