假设我有一个包含数百万行的表。使用JPA,迭代对该表的查询的正确方法是什么,以至于 我没有一个 包含数百万个对象 的内存列表 ?
例如,如果表很大,我怀疑以下内容会爆炸:
List<Model> models = entityManager().createQuery("from Model m", Model.class).getResultList();
for (Model model : models)
{
System.out.println(model.getId());
}
分页(循环和手动更新setFirstResult()
/ setMaxResult()
)真的是最好的解决方案吗?
编辑
:我针对的主要用例是一种批处理作业。如果需要很长时间才能运行就可以了。没有涉及Web客户端。我只需要为每一行“做某事”,一次一行(或一些小N)。我只是想避免将它们全部同时存储在内存中。
Java Persistence with Hibernate的第537页提供了一个使用的解决方案ScrollableResults
,但可惜它仅适用于Hibernate。
因此,似乎需要使用setFirstResult
/ setMaxResults
和手动迭代。这是我使用JPA的解决方案:
private List<Model> getAllModelsIterable(int offset, int max)
{
return entityManager.createQuery("from Model m", Model.class).setFirstResult(offset).setMaxResults(max).getResultList();
}
然后,像这样使用它:
private void iterateAll()
{
int offset = 0;
List<Model> models;
while ((models = Model.getAllModelsIterable(offset, 100)).size() > 0)
{
entityManager.getTransaction().begin();
for (Model model : models)
{
log.info("do something with model: " + model.getId());
}
entityManager.flush();
entityManager.clear();
em.getTransaction().commit();
offset += models.size();
}
}
有人能帮我吗?
注意:当通过WebClient exchange()方法获得对ClientResponse的访问权限时,必须始终使用body或toEntity方法之一,以确保释放资源并避免HTTP连接池的潜在问题。如果不需要响应内容,可以使用bodyToMono(void.class)。但是,请记住,如果响应确实有内容,连接将被关闭,并且不会被放回池中。 我可以调用WebClient并忽略结果吗?或者是否有一个通
我使用apache ignite缓存作为数据存储。想知道是否有方法从客户端对大型数据集合进行分页。我不需要或希望数百万的记录从服务器转移到我的网络/移动客户端。 这是一个有效的方法吗? 我看过使用游标,但API仅限于迭代器...
问题内容: 我正在开发一个使用大型MySQL表的spring应用程序。加载大表时,我得到一个,因为驱动程序试图将整个表加载到应用程序内存中。 我尝试使用 但是然后我打开的每个ResultSet都挂了; 在网上查看时,我发现发生这种情况是因为它尝试在关闭ResultSet之前尝试加载所有未读的行,但事实并非如此,因为我这样做是: 小表(3行)也会发生挂起,如果我不关闭RecordSet(在一种方法中
我正在使用Jpa和Hibernate。 我的项目中发生了一件非常奇怪的事情。 我有两个实体:学生和课程,多对多的关系。 很长一段时间内,一切都运行得很好,但突然我遇到了这个问题: 当我找到一个特定的学生(em.find)并使用getter(student.getcourses)返回其课程列表时,我只收到列表的一部分!如果我使用一个查询(“Select s.cources from Students
预备:代码存在于使用JPA的JavaWebApp中,并对其感到满意,因此完全脱离JPA并不是解决方案。 但我的部分是关于动态数据查询的。比如说,管理员可以编写sql查询,用户可以通过这些查询生成csv导出。 有了JDBC,我获得了很多关于ResultSet的元数据,我可以在我知道的地方获取字符串和整数。 JPA允许直接SQL查询,但我只能用作为