Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate对每一行使用sql调用来获取关系,而不是在子句中聚合为一行_Java_Hibernate - Fatal编程技术网

Java Hibernate对每一行使用sql调用来获取关系,而不是在子句中聚合为一行

Java Hibernate对每一行使用sql调用来获取关系,而不是在子句中聚合为一行,java,hibernate,Java,Hibernate,我有一个用户对象,其地址设置为地址。现在让我们假设我需要获取1000000个用户,并在一些报告中显示他们的地址 执行此操作的Hibernate方法是为User表创建一个sql调用,然后为每个用户创建另一个Address表调用。结果是总计100000次调用和很长的查询时间 另一方面,如果您聚合所有外键(例如User\u Id),并在sql调用中运行 FROM Address where User_Id IN (,,,,,,,,) 您将呼叫数减少到2个-一个呼叫用户表,一个呼叫地址表,以便在一次呼

我有一个
用户
对象,其
地址
设置为
地址
。现在让我们假设我需要获取1000000个用户,并在一些报告中显示他们的地址

执行此操作的
Hibernate
方法是为
User
表创建一个
sql
调用,然后为每个用户创建另一个
Address
表调用。结果是总计100000次调用和很长的查询时间

另一方面,如果您聚合所有外键(例如
User\u Id
),并在
sql调用中运行

FROM Address where User_Id IN (,,,,,,,,)
您将呼叫数减少到2个-一个呼叫用户表,一个呼叫地址表,以便在一次呼叫中获得所有1000000个所需地址

但这需要在应用程序方面做一些工作。不是很多工作,只是一个循环的
,但是仍然。有没有可能让Hibernate以高效的方式来做呢


请注意,
LAZY fetching
与此无关。对于我的用例,我需要一个
快速抓取

我建议您进行两次查询。我使用Java8流

Query query = session.createQuery("from User").setMaxResult(BATCH);
List<User> users = query.list();
final List<Integer> userIds = users.stream()
                                          .map(u -> u.getUserId()).collect(Collectors.toList());
query = session.createQuery("FROM Address where User_Id IN (:ids)").setListParametrs(userIds);
final List<Address> result = query.list();
Query Query=session.createQuery(“来自用户”).setMaxResult(批处理);
List users=query.List();
最终列表userid=users.stream()
.map(u->u.getUserId()).collect(Collectors.toList());
query=session.createQuery(“从用户Id所在的地址(:Id)”).setListParameters(用户Id);
最终列表结果=query.List();

我还想建议不要在一个查询中获得1000000行,使用批处理

我建议您提出两个问题。我使用Java8流

Query query = session.createQuery("from User").setMaxResult(BATCH);
List<User> users = query.list();
final List<Integer> userIds = users.stream()
                                          .map(u -> u.getUserId()).collect(Collectors.toList());
query = session.createQuery("FROM Address where User_Id IN (:ids)").setListParametrs(userIds);
final List<Address> result = query.list();
Query Query=session.createQuery(“来自用户”).setMaxResult(批处理);
List users=query.List();
最终列表userid=users.stream()
.map(u->u.getUserId()).collect(Collectors.toList());
query=session.createQuery(“从用户Id所在的地址(:Id)”).setListParameters(用户Id);
最终列表结果=query.List();


我还想建议不要在一个查询中获得1000000行,使用批处理

Hibernate将使用
连接生成单个查询。我不知道您正在使用哪种配置。
从用户u LEFT JOIN FETCH u.address中选择u。
将通过连接提供u地址。单个查询

Hibernate将使用
连接生成单个查询
。我不知道您正在使用哪种配置。
从用户u LEFT JOIN FETCH u.address中选择u。
将通过连接提供u地址。单查询

是的,这是我刚才提到的两个查询。但是您仍然需要收集用户ID,然后将每个地址与其用户进行匹配。再说一次,不是很多工作,但仍然。(感谢没有for循环的收集用户ID的酷新方法。)不,我不会一次获取一百万个对象。这只是一个例子。是的,这是我刚才提到的两个问题。但是您仍然需要收集用户ID,然后将每个地址与其用户进行匹配。再说一次,不是很多工作,但仍然。(感谢没有for循环的收集用户ID的酷新方法。)不,我不会一次获取一百万个对象。这只是一个例子。Andy为什么不直接获取所需的
地址
字段?@Antoniossss,因为这正是问题所在。在这种情况下,Hibernate将执行1000001个查询。设置
true
并亲自查看。Hibernate将使用
连接生成单个查询。我不知道您使用的是哪种配置。
从用户u LEFT JOIN FETCH u中选择u。address
将通过连接提供u
address
。单身queryYes,太好了。这应该是对这个问题的回答,我很乐意接受。你的愿望实现了:)安迪,你为什么不直接获取所需的
地址
字段?@antoniosss,因为这正是问题所在。在这种情况下,Hibernate将执行1000001个查询。设置
true
并亲自查看。Hibernate将使用
连接生成单个查询。我不知道您使用的是哪种配置。
从用户u LEFT JOIN FETCH u中选择u。address
将通过连接提供u
address
。单身queryYes,太好了。这应该是这个问题的答案,我很乐意接受。你的愿望实现了:)实际上,如果你不在用户和地址之间使用hibernate关系,这只是一个查询。但是当你这样做时,一个急切的获取会做一个额外的查询,如果你使用一个懒惰的获取,你以后在检索地址时就必须使用这个额外的查询。实际上,如果你不在用户和地址之间使用hibernate关系,这是一个单独的查询。但是当你这样做的时候,一个急切的抓取会做一个额外的查询,如果你使用一个懒惰的抓取,那么你以后在检索地址时必须使用额外的查询。