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

带有动态查询的Spring数据JPA分页(可分页)

李烨烁
2023-03-14

我有一个简单的查询如下“select * from USERS”。我还使用Pageable来启用分页。

此查询可能具有基于给定参数是否为 null 的可选谓词。

例如,如果给定了“code”参数且该参数不为空,则查询变为“select * from USERS where code =:code”;

据我所知,我不能使用@Query注释来实现这一点。我可以实现一个定制的存储库,并使用EntityManager创建一个动态查询。但是,我不确定如何将“可分页”与它集成在一起,以获得分页的结果。

我怎样才能做到这一点?

共有3个答案

杭永安
2023-03-14

例如,您必须使用querydsl,并根据非空参数构建其中

BooleanBuilder where = new BooleanBuilder();
...
    if(code  != null){
        where.and(YOURENTITY.code.eq(code));
    } 

并在执行查询后

    JPAQuery query = new JPAQuery(entityManager).from(..)               
            .leftJoin( .. )
            ...
            .where(where)

并使用您自己的页面

    MaPage<YOURENTITY> page = new MaPage<YOURENTITY>();
    page.number = pageNumber+1;

    page.content = query.offset(pageNumber*pageSize).limit(pageSize).list(...);

    page.totalResult = query.count();

我就是这样创建MyPage的

public class MaPage<T> {

    public List<T> content;
    public int number;
    public Long totalResult;
    public Long totalPages;
    ...
}

它可以工作,但是如果在查询中得到一个fetch,那么就会出现这个警告

2014年11月21日上午6:48:54 org.hibernate.hql.internal.ast。QueryTranslatorImpl列表
警告:HHH000104:使用集合提取指定的firstResult/maxResults;在内存中应用!

这将降低您的请求速度,因此解决方案是摆脱fetch并定义一个< code>@BatchSize(size=10)并使用< code>Hibernate.initialize(....)来获取集合和其他对象类型中的数据。

通过设置@BatchSize,显示相关实体的数据以避免延迟初始化异常

如何使用Spring Data和QueryDSL执行带分页的JPAQuery

宗政唯
2023-03-14

获取querydsl查询的页面结果有些复杂,因为您需要两个查询:一个用于查询总条目数,另一个用于查看页面中需要的条目列表。您可以使用以下超类:

public class QueryDslSupport<E, Q extends EntityPathBase<E>> extends QueryDslRepositorySupport {

  public QueryDslSupport(Class<E> clazz) {
    super(clazz);
  }

  protected Page<E> readPage(JPAQuery query, Q qEntity, Pageable pageable) {
    if (pageable == null) {
      return readPage(query, qEntity, new QPageRequest(0, Integer.MAX_VALUE));
    }
    long total = query.clone(super.getEntityManager()).count(); // need to clone to have a second query, otherwise all items would be in the list
    JPQLQuery pagedQuery = getQuerydsl().applyPagination(pageable, query);
    List<E> content = total > pageable.getOffset() ? pagedQuery.list(qEntity) : Collections.<E> emptyList();
    return new PageImpl<>(content, pageable, total);
  }

}
融宏伟
2023-03-14

这在使用QueryDSL(作为标准API的替代)的SpringData中很容易做到。以下QueryDSLPredicateExecutor方法支持开箱即用,如果不应用任何限制,您可以只将null作为谓词传递:

Page<T> findAll(com.mysema.query.types.Predicate predicate,
                Pageable pageable)

使用QueryDSL可能不适合您,但是如果您查看以下系列教程,您可能会得到一些想法。

http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-nine-conclusions/

作者在其指南第9部分的评论中实际讨论了您的场景。

 类似资料:
  • 问题内容: 我正在使用Spring Data JPA,当我用来定义一个 WITHOUT 的查询时,它可以工作: 但是,如果我添加第二个参数,则将无法正常工作,Spring将解析该方法的名称,然后抛出 异常 。这是错误吗? 问题答案: 在Spring论坛上提出了一个类似的问题,指出要应用分页,必须派生第二个子查询。因为子查询引用的是相同的字段,所以您需要确保查询对引用的实体/表使用别名。这意味着您在

  • 问题内容: 在一个网络项目中,将最新的spring-data(1.10.2)与MySQL 5.6数据库一起使用,我试图将本机查询与分页一起使用,但是在启动时遇到了问题。 根据spring-data文档中使用的示例50,可以指定查询本身和countQuery,如下所示: 出于好奇,在课堂上我可以看到它包含以下代码来检查其是否为有效的jpa查询: 我的查询中包含一个参数,所以是的,但它也在寻找或序列里

  • 在一个web项目中,使用最新的spring-data(1.10.2)和MySQL5.6数据库,我试图使用带分页的本机查询,但在启动时遇到的是。 根据示例50,在使用来自spring-data文档的@query时,可以指定查询本身和countQuery,如下所示: 出于好奇,在类中,我可以看到它包含以下代码,以检查它是否是有效的jpa查询: 我的查询包含一个参数,因此是,但它也在中查找一个或序列,我

  • 根据Spring文档https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.special-返回的参数不应发出计数查询。 但是随着我的Spring,它变得有点奇怪。 当使用page运行页面请求时,它不需要计数查询,我认为这是正确的。 但当我使用页面(或以上)调用存储库时,它突然在选择查询之后执

  • 我有一个简单的JpaRepository和一个finder,它返回按名为“number”的属性降序排列的记录。“number”属性也是我的实体的@Id。这很好,但是有数千条记录,所以我想返回一个页面而不是列表。 如果我将查找器更改为以下内容,则排序不再起作用。我尝试过使用可分页参数的排序功能,但不起作用。还删除了OrderByNumberDesc,但结果相同。 EDIT-添加控制器方法 以下是我的

  • 我尝试过用Spring Boot实现JPA存储库,它工作得很好。现在,如果我尝试在使用@query注释扩展JpaRepository的接口中实现自定义查询,它可以很好地返回bean列表(使用NamedQuery)。现在,当我尝试为自定义方法/查询使用分页时,它不起作用。 代码: 控制器: 服务 异常:java.lang.IllegalArgumentException:为TypedQuery[ja