【发布时间】:2021-03-24 22:05:07
【问题描述】:
我正在学习 Laravel,我正在使用 Laravel 5.2。我想了解 Eager Loading、Constraining Eager Loads 和 Lazy Eager Loading。这三者之间有什么相同点和不同点?你能为他们每个人举一个例子吗?我已经阅读了 Laravel 文档,但我仍然不明白。我希望你能给出更清楚的解释。谢谢。
【问题讨论】:
标签: php laravel laravel-5.2
我正在学习 Laravel,我正在使用 Laravel 5.2。我想了解 Eager Loading、Constraining Eager Loads 和 Lazy Eager Loading。这三者之间有什么相同点和不同点?你能为他们每个人举一个例子吗?我已经阅读了 Laravel 文档,但我仍然不明白。我希望你能给出更清楚的解释。谢谢。
【问题讨论】:
标签: php laravel laravel-5.2
简而言之:
Eager Loading 允许您有效地获取某些模型的关系。
Constraining Eager Loads 再次提高效率,但您可以限制结果,例如日期范围、特定 ID 等
Lazy Eager Loading 适用于您已经加载了父模型的情况
例子:
好的,假设您正在创建一个博客,您将在其中发布帖子,并且这些帖子可以有 cmets 和 likes。
场景 1:
您想获得所有Posts 及其Comments 和Likes。你会加载所有的Post,然后遍历它们并获取它们的comments 和likes?好吧,你可以,但这最终可能会非常昂贵,因为它最终可能会执行很多很多查询。或者您可以加载帖子,然后获取他们的 ids 并加载您需要的所有 cmets 用于那些 ids 以及他们喜欢的相同。这基本上就是 Laravel 对急切加载所做的。
场景 2(场景 1 的真实示例):
您正在为帖子创建供稿。所以,你已经加载了你所有的帖子,然后你想显示它有多少喜欢和 cmets,所以你会得到类似的东西(非常基本):
控制器:
$posts = App\Post::all();
return view('posts.index', compact('posts'));
刀片文件:
@foreach($posts as $post)
<h2>{{ $post->title }}</h2>
<p>{{ $post->description }}</p>
<p>
Likes: {{ $post->likes->count() }} <br>
Comments: {{ $post->comments->count() }}
</p>
@endforeach
上述方法可行,但对于每个循环,它实际上都是在查询数据库。将控制器更改为:
$posts = App\Post::with('likes', 'comments')->get();
return view('posts.index', compact('posts'));
然后将获得所有Posts 的comments 和likes,预先保存数据库并使您的应用程序更加高效。
场景 3
我想显示 Posts,但我只想显示最后 3 个 comments。
$posts = App\Post::with(['comments' => function ($query) {
$query->limit(3);
}]);
Lazy Eager Loading 用于当你已经加载了你的Posts,然后你需要在事后获得所有comments 或likes。原理相同,但您将使用load 而不是with。您可能使用 load 的另一个原因是,如果您将 Route model binding 用于您的控制器,那么 Post 将已被检索,但您仍想获得它的关系。
希望对您有所帮助!
【讨论】:
eager loading 和 lazy eager loading 之间的主要区别 - 前者适用于同时加载父母的情况,后者适用于已经加载父母的情况。
constraint eager loads有什么区别呢?
constraint eager loads 允许您限制查询,例如向查询添加 where 子句。因此,如果您想获取关系的所有模型,则无需添加约束,如果您确实想以某种方式限制它们,则添加这些约束。