对于休眠中的N+1问题,有什么解决办法?[英] What is the solution for the N+1 issue in hibernate?

本文是小编为大家收集整理的关于对于休眠中的N+1问题,有什么解决办法?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我知道 N+1 问题是执行一个查询以获取 N 条记录,执行 N 个查询以获取一些关系记录.

但是在 Hibernate 中如何避免呢?

推荐答案

假设我们有一个类 Manufacturer 与 Contact 是多对一的关系.

我们通过确保初始查询获取加载我们需要的处于适当初始化状态的对象所需的所有数据来解决这个问题.一种方法是使用 HQL 提取连接.我们使用 HQL

"from Manufacturer manufacturer join fetch manufacturer.contact contact"

使用 fetch 语句.这会导致内部连接:

select MANUFACTURER.id from manufacturer and contact ... from 
MANUFACTURER inner join CONTACT on MANUFACTURER.CONTACT_ID=CONTACT.id

使用 Criteria 查询我们可以得到相同的结果

Criteria criteria = session.createCriteria(Manufacturer.class);
criteria.setFetchMode("contact", FetchMode.EAGER);

创建 SQL:

select MANUFACTURER.id from MANUFACTURER left outer join CONTACT on 
MANUFACTURER.CONTACT_ID=CONTACT.id where 1=1

在这两种情况下,我们的查询都会返回带有初始化联系人的制造商对象列表.只需运行一次查询即可返回所需的所有联系人和制造商信息

更多信息,请点击 问题解决方案

本文地址:https://www.itbaoku.cn/post/627596.html

问题描述

I understand that the N+1 problem is where one query is executed to fetch N records and N queries to fetch some relational records.

But how can it be avoided in Hibernate?

推荐答案

Suppose we have a class Manufacturer with a many-to-one relationship with Contact.

We solve this problem by making sure that the initial query fetches all the data needed to load the objects we need in their appropriately initialized state. One way of doing this is using an HQL fetch join. We use the HQL

"from Manufacturer manufacturer join fetch manufacturer.contact contact"

with the fetch statement. This results in an inner join:

select MANUFACTURER.id from manufacturer and contact ... from 
MANUFACTURER inner join CONTACT on MANUFACTURER.CONTACT_ID=CONTACT.id

Using a Criteria query we can get the same result from

Criteria criteria = session.createCriteria(Manufacturer.class);
criteria.setFetchMode("contact", FetchMode.EAGER);

which creates the SQL :

select MANUFACTURER.id from MANUFACTURER left outer join CONTACT on 
MANUFACTURER.CONTACT_ID=CONTACT.id where 1=1

in both cases, our query returns a list of Manufacturer objects with the contact initialized. Only one query needs to be run to return all the contact and manufacturer information required

for further information here is a link to the problem and the solution