Tho*_*ang 5 hibernate jpa spring-data-jpa spring-boot
我得到了这个存储库代码:
\n@Query(value = "select distinct r from Reference r " +\n "inner join fetch r.persons " +\n "left outer join fetch r.categories " +\n "left outer join fetch r.keywords " +\n "left outer join fetch r.parentReferences",\n countQuery = "select count(distinct r.id) from Reference r " +\n "inner join r.persons " +\n "left outer join r.categories " +\n "left outer join r.keywords " +\n "left outer join r.parentReferences")\nPage<Reference> findsAllRelevantEntries(Pageable pageable);\nRun Code Online (Sandbox Code Playgroud)\n当我对该查询运行测试时,我收到此 Hibernate 警告:
\nHHH000104: firstResult/maxResults specified with collection fetch; applying in memory!
@Test\nvoid testFindAllRelevantAsync() throws ExecutionException, InterruptedException {\n CompletableFuture<Page<Reference>> all = referenceService.findAllRelevantAsync(PageRequest.of(1, 20));\n CompletableFuture.allOf(all).join();\n assertThat(all.get()).isNotNull();\n assertThat(all.get()).isNotEmpty();\n}\nRun Code Online (Sandbox Code Playgroud)\n存储库代码封装在此处未显示的服务方法中。它(服务方法)只是将服务的调用编组到存储库并返回。
\n此外,生成的 sql 查询不会生成limit子句。尽管它确实引发了两个查询。
一个用于count,另一个用于获取所有记录。
\n因此它会获取所有记录并在内存中应用分页。
\n这会导致查询执行速度非常慢。
我怎样才能使分页与此查询一起使用?
\n编辑
\n我知道这里经常建议作为解决方案:\n如何避免警告“使用集合获取指定的firstResult/maxResults;在内存中应用!” 当使用休眠时?
\n有没有办法使用 Spring Data JPA 实现分页?\n我不想\xc2\xb4t 想要硬连线 an EntityManager,也不想\n从 a 扩展代码BasicTransformerAdapter
我自己找到了解决方法。基于此:
如何避免警告“使用集合获取指定的firstResult/maxResults;在内存中应用!” 当使用休眠时?
首先:通过分页获取Id:
@Query(value = "select distinct r.id from Reference r " +
"inner join r.persons " +
"left outer join r.categories " +
"left outer join r.keywords " +
"left outer join r.parentReferences " +
"order by r.id",
countQuery = "select count(distinct r.id) from Reference r " +
"inner join r.persons " +
"left outer join r.categories " +
"left outer join r.keywords " +
"left outer join r.parentReferences " +
"order by r.id")
Page<UUID> findsAllRelevantEntriesIds(Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
第二:使用Id进行in查询
@Query(value = "select distinct r from Reference r " +
"inner join fetch r.persons " +
"left outer join fetch r.categories " +
"left outer join fetch r.keywords " +
"left outer join fetch r.parentReferences " +
"where r.id in ?1 " +
"order by r.id",
countQuery = "select count(distinct r.id) from Reference r " +
"inner join r.persons " +
"left outer join r.categories " +
"left outer join r.keywords " +
"left outer join r.parentReferences ")
@QueryHints(value = {@QueryHint(name = "hibernate.query.passDistinctThrough", value = "false")},
forCounting = false)
List<Reference> findsAllRelevantEntriesByIds(UUID[] ids);
Run Code Online (Sandbox Code Playgroud)
注意:
我得到的List<Reference不是 a,Pageable所以你必须Pageable自己构建,如下所示:
private Page<Reference> processResults(Pageable pageable, Page<UUID> result) {
List<Reference> references = referenceRepository.findsAllRelevantEntriesByIds(result.toList().toArray(new UUID[0]));
return new PageImpl<>(references, pageable, references.size());
}
Run Code Online (Sandbox Code Playgroud)
这看起来不太好,并且执行了两个语句,但它使用 进行查询limit,因此仅获取所需的记录。
| 归档时间: |
|
| 查看次数: |
4513 次 |
| 最近记录: |