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

Spring数据分页并排序NamedNativeRequesty(JPA Hibernate MySql)

丁书
2023-03-14

我在Spring数据(JPA Hibernate MySQL)应用程序中使用NamedNativeQueries和SqlResultSetMappings,我已经成功地完成了分页,但没有完成排序。

我尝试了两种形式的查询:

@NamedNativeQuery(
  name = "DatasetDetails.unallocatedDetailsInDataset",
  resultClass = DatasetDetails.class,
  resultSetMapping = "DatasetDetails.detailsForAllocation",
  query = "SELECT dd.id, fk_datasets_id, fk_domains_id, fk_sources_id, dom.name AS domain, " +
  "src.name AS source " +
  "FROM datasets AS d " +
  "JOIN datasets_details AS dd ON dd.fk_datasets_id = d.id " +
  "JOIN sources AS src ON src.id = dd.fk_sources_id " +
  "JOIN domains AS dom ON dom.id = dd.fk_domains_id " +
  "WHERE fk_datasets_id = :datasetId " +
  "AND dd.id NOT IN (" +
  "SELECT fk_datasets_details_id from allocations_datasets_details)  \n/* #page */\n"),

第二种方法是在第二个查询中简单地使用计数符号,而不是使用#页面符号。

@NamedNativeQuery(
  name = "DatasetDetails.unallocatedDetailsInDataset.count",
  resultClass = DatasetDetails.class,
  resultSetMapping = "DatasetDetails.detailsForAllocation",
  query = "SELECT count(*)
....

这两种方法都适用于分页,但忽略了排序。

这是存储库:

public interface DatasetDetailsRepository extends PagingAndSortingRepository<DatasetDetails, Long> {
    @Query(nativeQuery = true)
    List<DatasetDetails> unallocatedDetailsInDataset(@Param("datasetId") long datasetId,
                                                     @Param("page") Pageable page);
}

可分页页面的组装方式如下:

Sort sort = Sort.by(Sort.Order.asc(DatasetDetails.DOMAIN), Sort.Order.asc(DatasetDetails.SOURCE));
Pageable page = PageRequest.of(page, limit, sort);

没有抛出错误,但排序没有完成,也没有生成ORDER BY。

通过#{#page}显式添加类似ORDER的内容将无法编译。

共有1个答案

云宜人
2023-03-14

我也遇到了同样的问题,我必须使用一个名为NamedNativeQuery的函数按不同的列和方向动态过滤/排序;显然,排序被忽略了。我发现这个解决方法不一定很好,但确实有效:

对于存储库:

List<MyEntity> findMyEntities(
    @Param("entityId") long entityId,
    @Param("sortColumn") String sortColumn,
    @Param("sortDirection") String sortDirection,
    Pageable page);

本机查询如下所示:

@NamedNativeQueries({
  @NamedNativeQuery(name = "MyEntity.findMyEntities",
      query = "select e.field1, e.field2, ..." +
              " from my_schema.my_entities e" +
              " where condition1 and condtition2 ..." +
              " order by " +
              "   CASE WHEN :sortColumn = 'name'      and :sortDirection = 'asc'  THEN e.name      END ASC," +
              "   CASE WHEN :sortColumn = 'birthdate' and :sortDirection = 'asc'  THEN e.birthdate END ASC," +
              "   CASE WHEN :sortColumn = 'name'      and :sortDirection = 'desc' THEN e.name      END DESC," +
              "   CASE WHEN :sortColumn = 'birthdate' and :sortDirection = 'desc' THEN e.birthdate END DESC" +
  ),
  @NamedNativeQuery(name = "MyEntity.findMyEntities.count",
          query = "select count(*) from my_schema.my_entities e" +
                  " where condition1 and condtition2 ..." +
                  "  and :sortColumn = :sortColumn and :sortDirection = :sortDirection"
  )
})

注意,在count查询中,我使用了两个冗余条件:sortColumn和sortDirection,因为一旦在存储库函数中指定为Param,就需要在实际查询中使用它们。

调用函数时,在我的服务中有一个布尔值指示方向,还有一个字符串指示排序列,如下所示:

public Page<MyEntity> serviceFindFunction(Long entityId, String sortColumn, Boolean sortDirection, Integer pageNumber, Integer pageSize) {
    String sortDir = (sortDirection) ? 'asc' : 'desc';
    Pageable pageable = new PageRequest(pageNumber, pageSize); // Spring Data 1.0 syntax

    // for Spring Data 2.0, as you were using, simply:
    // Pageable pageable = PageRequest.of(pageNumber, pageSize);

    return entityRepository.findMyEntities(entityId, sortColumn, sortDir, pageable)
}

关于这一点,我不喜欢的两件事是在count查询中重复使用sortColumn和sortDirection参数,以及我编写order by语句的方式。使用单独的CASE语句的原因是,我排序的列的数据类型不同,如果它们不兼容(例如,nvarchar和date),查询将失败,并出现错误:

从字符串转换日期和/或时间时转换失败

我也可能嵌套条件,即首先为方向做一个案例,为列做一个内部案例,但我的SQL技能只做了这么多。

希望这有帮助!欢迎任何反馈或改进。

 类似资料:
  • 我试图指定一个用注释的存储库方法和一个带有对象的Pagable: 编辑1:此存储库正在扩展分页和排序存储库。 对象使用以下方法签名指定: 但生成的输出查询没有排序选项,例如: ...在我期待的时候: 这里有人遇到过这样的问题吗?我使用的是Spring Boot 1.5。x。

  • 我使用了spring boot(1.3.5)、spring-data、spring-data-jpa、JPA(hibernate/hsqldb)。 代码: 控制器: 我试着 也是,但不起作用。 浏览器输出: SQL无效!额外的“:”和重复的“ASC ASC”。 控制台输出:

  • 分页 使用 limit 和 offset 来控制分页数据: limit 指定该请求返回的结果个数 offset 偏移量,指定该请求返回的结果的起始位置 默认 limit 为 20, offset 为 0,我们也可以手动指定 limit 和 offset 来控制。例如,每页展示 100 条数据,需要获取第五页的数据,将 limit 设置为 100、offset 设置为 400 即可。limit 最大

  • {% tabs first=”SDK 1.1.0 及以上版本”, second=”SDK 1.1.0 以下版本” %} {% content “first” %} SDK 1.1.0 及以上版本 分页 使用 limit 和 offset 来控制分页数据: limit 指定该请求返回的结果个数 offset 偏移量,指定该请求返回的结果的起始位置 默认 limit 为 20, offset 为 0,

  • 我正在尝试在spring MVC中实现分页和排序。根据我的理解,我们可以使用PagingAndSortingRepository或JpaRepository(http://springinpractice.com/2012/05/11/pagination-and-sorting-with-spring-data-jpa)。 但这两种方法都使用默认的findAll方法来执行此操作。 我希望创建我自

  • 文档结构-消息{obj_id,post_id,message_time,message_text}和@key是obj_id。 问题声明:我只想要fetch all the data包含post_id:'anything'并基于message_time进行排序,并且每次都想在结果中进行自定义分页。现在,我正在根据以下链接实现代码:https://stackoverflow.com/a/1007753