当前位置: 首页 > 知识库问答 >
问题:

如何在使用QueryDSL编写动态查询的同时使用Spring的分页(使用Pageable)?

童铭晨
2023-03-14

我正在尝试将分页与QueryDSL一起使用--使用com.mysema.QueryDSL包。

我所有的Querydsl查询类型都像这样-

@Generated("com.mysema.query.codegen.EntitySerializer")
public class QCountry extends EntityPathBase<Country> {...}

目前,我的存储库实现类看起来像这样-

     @Override
            public Page<Country> findPaginatedCountries(String country, Optional<String> status, Pageable pageable) {

                QCountry qCountry= QCountry.someObject;
                QActiveCountry qActiveCountry = QActiveCountry.activeCountry;

               JPAQuery jpaQuery = new JPAQuery(entityManager);

                QueryBase queryBase = jpaQuery.from(qCountry).innerJoin(qActiveCountry).fetch()
                        .where(qCountry.codeLeft.country.upper().eq(country.toUpperCase()))
                        .where(qCountry.codeRight.country.upper().eq(country.toUpperCase()));



                if(status.isPresent()){
                    queryBase = queryBase.where(qActiveCountry.id(qCountry.active.id))
                            .where(qActiveCountry.status.upper().eq(status.get().toUpperCase()));
                }
.......}

现在,我希望这个动态查询返回一个分页的响应。我想使用Spring的分页来实现,而不是手动设置偏移量、大小等。

我知道我可以使用QueryDslRepositorySupport类--如这里实现的-https://github.com/keke77/spring-data-jpa-sample/blob/master/spring-data-jpa/src/main/java/com/gmind7/bakery/employeeereRepositoryimpl.java

来自上述链接的示例代码-

@Override
    public Page<Employees> QFindByOfficeCode(long officeCode, Pageable pageable) {
        //JPAQuery query = new JPAQuery(em);
        JPQLQuery query = from(QEmployees.employees).where(QEmployees.employees.officeCode.eq(officeCode));
        query = super.getQuerydsl().applyPagination(pageable, query);
        SearchResults<Employees> entitys = query.listResults(QEmployees.employees);
        return new PageImpl<Employees>(entitys.getResults(), pageable, entitys.getTotal());
    }      

然而,要那样做-

  1. 我需要将JPQLQuery对象传递给applyPagination方法。我如何在不更改代码的情况下做到这一点(当然,repository类将扩展QueryDslRepositorySupport类)。当前,我正在使用JPAQuery(如您所见)。

下面的代码段-

 Page<T> page = QueryDslPredicateExecutor.findAll(org.springframework.data.querydsl.Predicate predicate, Pageable pageable)

但是,我在两个表之间进行联接,然后使用where子句过滤结果(正如您在上面的代码中看到的)。我如何在上面的findAll方法中传递谓词对象?不确定如何在其中包含联接。

如果问题不清楚请让我知道,我可以补充更多细节。

编辑:Country和ActiveCountry之间存在多对一的关系。Country类具有ActiveCountry引用。我们必须在两个ID之间进行连接。Country可能具有空的ActiveCountry。因此,我们希望活动国家/地区有一个内部仅联接的非空值

@ManyToOne
@JoinColumn(name="id")
ActiveCountry active;

共有1个答案

东典
2023-03-14

步骤1:使用@QueryEntity注释实体类

@Entity
@QueryEntity
public class Country {}

这似乎已经解决了,因为问题显示q类。

步骤2:使存储库接口扩展QueryDSLPredicateExecutor

public interface CountryRepository
                 extends PagingAndSortingRepository<Country, Long>
                         , QueryDslPredicateExecutor<Country> {
}

步骤3:调用QuerydsLPredicateExecutor提供的page findAll(谓词查询,可分页页面) 方法

public Page<Country> getCountries(String country, Optional<String> status, Pageable page) {
  QCountry root = QCountry.country;

  BooleanExpression query = root.codeLeft.country.equalsIgnoreCase(country);
  query = query.and(root.codeRight.country.equalsIgnoreCase(country));

  if (status.isPresent()) {
    query = query.and(root.active.status.equalsIgnoreCase(status));
  }

  return countryRepository.findAll(query, page);
}
 类似资料:
  • QueryDSL定义了一个接口,通过调用或可以轻松地为任何字段获取该接口的实例。Spring Data JPA的接口甚至有一个方法,它将作为参数。 但是对QueryDSL一无所知,它有自己定义查询排序顺序的方法,即。它可以包含许多,它们与非常相似,只是它们不是类型安全的。 所以,如果我想做使用排序的分页查询,真的没有办法使用QueryDSL来定义它吗?

  • 问题内容: 问题答案: 这是从MySQL数据库知识库中获得的: LIMIT子句可用于约束SELECT语句返回的行数。 LIMIT接受一个或两个数字参数,这两个参数都必须是非负整数常量(使用预处理语句时除外)。 为了使查询正常工作,您需要将其编写为 准备好的语句 ,然后执行该 语句 。

  • 在我的情况下,我有一个审查实体,它由审查状态和提交日期组成。 我正在尝试使用JpaRepository,但我不确定如何使用它来支持以下搜索查询。 我可以看到(参考http://docs.spring.io/spring-data/jpa/docs/1.4.3.release/reference/html/jpa.repositories.html),我们可以为特定的查询定义方法,比如FindByN

  • 为了简化这个问题,我们有一个类/餐桌酒(餐桌“wines”),除其他属性外,它具有: null 我试图在我的存储库中创建一个搜索方法,以供RestController使用。 RestController中的方法声明如下所示: 我现在要做的是:为数据库创建一个查询,如果给出了searchTerm,就使用该数据库,与Origin相同。并且应该是可分页的。示例: 这(除了超级丑,特别是对于更多属性)很可

  • 问题内容: 我有5个表或表要从\查询 我的语法我喜欢这样 问题是,当我运行此命令时,我收到一条错误消息:“ .....您在SQL WHERE Patient_ID =吗?附近有错误?” 当我使用system.out.println(sql2)输出sql时; 值未在sql2中设置 问题答案: 当您准备一条语句时,数据库将构造一个执行计划,如果表不存在,则该计划无法执行。换句话说,Placehodle

  • 如何使用@ Query(value = " SELECT * FROM do _ not _ track WHERE(user _ id = 7)AND(' 2022-06-25 ' BETWEEN FROM _ date AND to _ date)OR(' 2022-06-30 ' BETWEEN FROM _ date AND to _ date)",nativeQuery = true)在