找回密码
 立即注册
首页 业界区 业界 QueryDsl动态排序的实现

QueryDsl动态排序的实现

龙骋唧 2025-7-9 22:03:15
写在前面,最近项目持久层框架需要使用JPA+QueryDsl,而网上相关的资料特别少。我将在JPA和QueryDsl标签下记录学习过程中遇到的问题和解决方案,希望能帮到有需要的小伙伴。
本文介绍使用QueryDsl实现动态排序的方法,即前端动态地向后端传递排序字段和排序规则,后端返回相应的结果。
步骤一

在项目的util包下创建一个QueryDslSortUtil工具类,直接复制粘贴以下代码即可。
  1. public class QueryDslSortUtil {
  2.     /**
  3.      * 将字段名和排序方向转换成 QueryDSL 的 OrderSpecifier
  4.      *
  5.      * @param sortField 排序字段名
  6.      * @param sortOrder 排序方向 (asc或desc)
  7.      * @param pathBase  Q类对象(例如QArticle.article)
  8.      * @return OrderSpecifier
  9.      */
  10.     public static <T> OrderSpecifier<?> buildSort(String sortField, String sortOrder, EntityPathBase<T> pathBase) {
  11.         Order order = "asc".equalsIgnoreCase(sortOrder) ? Order.ASC : Order.DESC;
  12.         Path<T> path = Expressions.path(pathBase.getType(), pathBase, sortField);
  13.         return new OrderSpecifier(order, path);
  14.     }
  15. }
复制代码
步骤二

在Repository中调用QueryDslSortUtil工具类的buildSort方法,到这里就可以正常使用了。示例代码如下。
  1. @Component
  2. public class ArticleAdvancedRepositoryImpl implements ArticleAdvancedRepository {
  3.     @Resource
  4.     private JPAQueryFactory jpaQueryFactory;
  5.     @Override
  6.     public Page dynamicFindAll(int page, int size, ArticleQueryVO articleQueryVO) {
  7.         Pageable pageable = PageUtil.handlePage(page, size); //分页对象
  8.         QArticle qArticle = QArticle.article; //这里以Article实体为例,请根据实际情况进行修改
  9.         //构建动态排序
  10.         OrderSpecifier<?> orderSpecifier = QueryDslSortUtil.buildSort(
  11.                 articleQueryVO.getSortField().name(), //前端传来的排序字段
  12.                 articleQueryVO.getSortOrder().name(), //前端传来的排序规则(升序/降序)
  13.                 qArticle //Article实体对应的Q类对象
  14.         );
  15.         //主查询
  16.         List results = jpaQueryFactory.select(...) //省略了投影的字段,请根据实际需要编写
  17.                 .from(qArticle)
  18.                 .orderBy(orderSpecifier)
  19.                 .offset(pageable.getOffset())
  20.                 .limit(pageable.getPageSize())
  21.                 .fetch();
  22.         //以下代码逻辑省略
  23.         //...
  24.         //计算总行数
  25.         Long totalCount = Optional.ofNullable(jpaQueryFactory.select(qArticle.count())
  26.                 .from(qArticle)
  27.                 .fetchOne()).orElse(0L);
  28.         return new PageImpl<>(results, pageable, totalCount);
  29.     }
  30. }
复制代码
补充

QueryDSL提供了严格的类型检查。return new OrderSpecifier(order, path);会出现警告,但不影响使用。
如果希望完全消除警告,可以将步骤一的buildSort方法替换成以下代码:
  1.    public static <T extends Comparable<? super T>> OrderSpecifier<?> buildSort(String sortField, String sortOrder, EntityPathBase<T> pathBase) {
  2.        Order order = "asc".equalsIgnoreCase(sortOrder) ? Order.ASC : Order.DESC;
  3.        Path<T> path =Expressions.path(pathBase.getType(), pathBase, sortField);
  4.        return new OrderSpecifier<>(order, path);
  5.    }
复制代码
重要: 如果使用上述修改后的buildSort方法,实体类必须要实现Comparable接口,否则无法通过编译。
  1. public class Article implements Comparable{
  2.     //...实体类的属性
  3.     @Override
  4.     public int compareTo(Article o) {
  5.         //...实现比较的逻辑
  6.         return 0;
  7.     }
  8. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册