Java 带有Stream的Spring JPA存储库<;实体>;
我无法理解存储库方法的Java 带有Stream的Spring JPA存储库<;实体>;,java,spring,spring-data-jpa,java-stream,Java,Spring,Spring Data Jpa,Java Stream,我无法理解存储库方法的流返回类型与列表有何不同 我在下面用fetchsize=1编写了一个简单的方法,但是我最终从表中获取了所有4条记录,这与列表类似。我错过什么了吗?它是否应该只提取提示中指定的1条记录。如果它获取1条记录,那么如何获取剩余的3条记录?完成了多少数据库调用 @QueryHints(value = { @QueryHint(name = HINT_FETCH_SIZE, value = "1"), @QueryHint(name
流
返回类型与列表
有何不同
我在下面用fetchsize=1编写了一个简单的方法,但是我最终从表中获取了所有4条记录,这与列表类似。我错过什么了吗?它是否应该只提取提示中指定的1条记录。如果它获取1条记录,那么如何获取剩余的3条记录?完成了多少数据库调用
@QueryHints(value = {
@QueryHint(name = HINT_FETCH_SIZE, value = "1"),
@QueryHint(name = HINT_CACHEABLE, value = "false"),
@QueryHint(name = HINT_READONLY, value = "true"), })
@Query("SELECT s FROM Customer s")
public Stream<Customer> findAllStream8();
@QueryHints(值={
@QueryHint(name=HINT\u FETCH\u SIZE,value=“1”),
@QueryHint(name=HINT\u CACHEABLE,value=“false”),
@QueryHint(name=HINT\u READONLY,value=“true”),})
@查询(“从客户s中选择s”)
公共流findAllStream8();
服务:
@Transactional(readOnly=true)
公共列表findAllStream(){
try(Stream-streamCustomer=repository.findAllStream8()){
返回streamCustomer.collect(Collectors.toList());
}捕获(例外e){
e、 printStackTrace();
}
返回数组.asList(新客户(“流客户”);
}
控制器:
@GetMapping(“/customer/allStream”)
公共列表FindAllCustomerStream(){
返回cs.findAllStream();
}
您的第一个问题在这里得到了很好的回答:
关于您的代码,HINT\u FETCH\u SIZE
用于限制每次迭代中获取的项目数量,直到它到达所有项目。它将为每个迭代获取1个项目,在您的例子中是4个迭代
要限制返回项目的数量,可以使用按名称限制查询(例如:findFirst()或findTop1()。请看这里:
或者您可以使用setMaxResults()
限制查询结果
criteria.setMaxResults(1);
Spring数据使用特定于提供者的实现来流化结果
(Hibernate使用ScrollableResultSet,EclipseLink使用
可滚动光标)。它减少了内存的消耗量,并且
对数据库的查询调用。正因为如此,它的速度也比
前面提到的两种解决办法
检查hibernate对此的状态
调用collect方法后,流将自动关闭,
因为没有理由保持底层JDBC结果集处于打开状态,如果
无法重用该流
查询流只是为了更好地分配资源和内存而发明的一种新机制
在下一行的示例中
return streamCustomer.collect(Collectors.toList());
在收集过程中,您让它从数据库中读取所有实体,并在列表中收集它们。根据您的偏好,我怀疑每次读取1行(1个实体客户)时,它会在数据库中运行4次
如果在流期间您跳过了我在上面发布的hibernate的查询流链接中指出的一些元素,那么它就不会从数据库中读取这些元素
因此,如果您有streamCustomer.skip(2).collect(Collectors.toList())代码>
它将只从数据库中读取2个元素,并将命中数据库2次。因为您将从流中跳过2个元素,所以不需要将它们带到流中
如果你有
streamCustomer.limit(3.collect(Collectors.toList())代码>
它将从该流中读取3个实体,并将它们收集到您的列表中。所以,它会命中数据库3次,每次获取1行(1个客户实体)
在我看来,这就是如何使用它来更好地分配内存和资源