2014-09-23 172 views
14

我真的很想了解with()方法和load()方法之间的区别,但并不能真正理解。laravel with()方法与load()方法

正如我所见,使用with()方法是“更好”,因为我渴望加载关系。看起来,如果我使用load()加载关系,就好像我将使用hasMany()(或任何其他与对象之间关系相关的方法)一样。

我弄错了吗?

回答

32

两者都完成了相同的最终结果 - 急切地将相关模型加载到第一个上。事实上,他们都运行完全相同的两个查询。主要区别在于with()在初始查询(例如all(),first()find(x))后立即加载相关模型。当使用load()时,首先运行初始查询,然后在稍后的某个时刻加载关系。

“渴望”在这里是指我们对特定结果相关联的所有相关模型只用一个查询,而不是让运行ñ查询,其中ñ是项目的数量设置在最初的集合中。


如果我们急于负载使用with(),例如使用with()

预先加载:

$users = User::with('comments')->get(); 

......如果我们有5个用户,下面的两个查询得到立即执行:

select * from `users` 
select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5) 

...并且我们最终得到了一系列附有用户模型注释的模型,因此我们可以执行类似于$users->comments->first()->body的操作。


“懒人” 使用预先加载load()

或者,我们可以先通过获取初始结果这两个查询分开,:

$users = User::all(); 

它运行:

select * from `users` 

然后,如果我们决定我们需要所有这些用户的相关评论,我们可以在事后急于加载它们:

$users = $users->load('comments'); 

它运行第二个查询:

select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5) 

...我们结束了相同的结果,只需分成两步。再次,我们可以致电$users->comments->first()->body去任何项目的相关模型。


为什么要用load()with()load()可让您根据某些动态条件决定稍后是否需要运行第二个查询。但是,如果没有问题需要访问所有相关项目,请使用with()。 (该文档还引用一个缓存的好处是用负载(),但我不熟悉的,事实上,我相信load()结果不缓存。)


的替代品,替代这些将循环通过初始结果集并查询每个项目的hasMany()关系。这将最终在此示例中运行n + 1查询,或者。急于加载,无论是与with()或更高版本与load()预先完成,只运行查询。

+0

谢谢!我仍然有一个问题,为什么我不使用急切加载然后使用正常的'hasMany()'方法? (我认为对于我的答案的一个解决方案是,只要我只与一个用户打交道,无论我是否使用热切加载或无关紧要,因为它会运行2个查询呢?) – kfirba 2014-09-24 06:39:15

+1

这取决于什么你正在处理的数据。如果您只对相关模型注释感兴趣,那么在我们的示例中只需查询'hasMany()'关系方法:'$ users = User :: find(1) - > comments;',它将仅返回信息关于评论,而不是用户。但是,如果您还需要从初始模型(用户)访问数据,则需要使用('comments') - > get();然后使用$ user = User :: where('id','1') - >。 '会给你一个集合,包括来自用户表的数据*和*他们的相关评论。无论哪种方式,都会运行2个相同的查询,但结果集合是不同的。 – damiani 2014-09-24 12:33:53

+0

可以'load'像'with'一样嵌套吗?像这里 - https://stackoverflow.com/questions/47048804/get-related-data-through-relation – Blagoh 2017-11-19 04:32:47