为什么 "with" 会在 Eloquent 中产生多个查询
How come "with" results in multiple queries in Eloquent
从这里开始:https://laravel-news.com/eloquent-eager-loading
运行 这一行:App\Post::with('author.profile')->get();
导致执行 3 个查询:
[2017-08-04 07:27:27] local.INFO: select * from `posts`
[2017-08-04 07:27:27] local.INFO: select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [1,2,3,4,5]
[2017-08-04 07:27:27] local.INFO: select * from `profiles` where `profiles`.`author_id` in (?, ?, ?, ?, ?) [1,2,3,4,5]
怎么会?
有没有一种简洁的方法可以在一个查询中执行此操作?
我希望生成的查询类似于:
SELECT *
FROM posts, authors, profiles
WHERE posts.author_id = author.id
AND author.profile_id = profiles.id
它仍然比延迟加载好得多,这意味着每个查询都是单独的。
您的期望不会如您所想。您可以改用加入。
像这样:
\DB::table('posts as p')
->join('authors as a', 'p.author_id', '=', 'a.id')
->join('profiles as pr', 'pr.id', '=', 'a.profile_id')
->get();
Eloquent 执行这样的查询,因此它可以为每一行数据混合一个单独的模型。这对于在加载模型后启用其他 Eloquent 功能很重要。通过预加载,数字查询始终是可预测的。 App\Post::with('author.profile')->get();
将始终执行三个查询,无论帖子、作者或个人资料的数量如何。如果不预先加载,它将 运行 查询数量成倍增加,具体取决于返回的记录数。这是 Eloquent 实施 Active Record 设计模式的结果。
"cleaner" 查询数据的示例本质上是在进行连接。您可以使用联接在一个查询中获取各种关系的所有数据。 Laravel 上下文中的缺点是所有数据都将存在于 Post
模型中,即使它来自三个不同的表。如果您只想快速显示所有数据,这很好,但在尝试操作和更新数据时会变得更加困难。
这更多是关于使用 Active Record 的问题,而不是针对 Eloquent 本身。支持和反对使用活动记录的争论有很多,我不会深入探讨。有关更多信息,我建议您阅读 Active Record(由 Eloquent 使用)、Data Mapper(由 Doctrine 使用)或更一般的 ORM 设计模式。
从这里开始:https://laravel-news.com/eloquent-eager-loading
运行 这一行:App\Post::with('author.profile')->get();
导致执行 3 个查询:
[2017-08-04 07:27:27] local.INFO: select * from `posts`
[2017-08-04 07:27:27] local.INFO: select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [1,2,3,4,5]
[2017-08-04 07:27:27] local.INFO: select * from `profiles` where `profiles`.`author_id` in (?, ?, ?, ?, ?) [1,2,3,4,5]
怎么会? 有没有一种简洁的方法可以在一个查询中执行此操作?
我希望生成的查询类似于:
SELECT *
FROM posts, authors, profiles
WHERE posts.author_id = author.id
AND author.profile_id = profiles.id
它仍然比延迟加载好得多,这意味着每个查询都是单独的。
您的期望不会如您所想。您可以改用加入。
像这样:
\DB::table('posts as p')
->join('authors as a', 'p.author_id', '=', 'a.id')
->join('profiles as pr', 'pr.id', '=', 'a.profile_id')
->get();
Eloquent 执行这样的查询,因此它可以为每一行数据混合一个单独的模型。这对于在加载模型后启用其他 Eloquent 功能很重要。通过预加载,数字查询始终是可预测的。 App\Post::with('author.profile')->get();
将始终执行三个查询,无论帖子、作者或个人资料的数量如何。如果不预先加载,它将 运行 查询数量成倍增加,具体取决于返回的记录数。这是 Eloquent 实施 Active Record 设计模式的结果。
"cleaner" 查询数据的示例本质上是在进行连接。您可以使用联接在一个查询中获取各种关系的所有数据。 Laravel 上下文中的缺点是所有数据都将存在于 Post
模型中,即使它来自三个不同的表。如果您只想快速显示所有数据,这很好,但在尝试操作和更新数据时会变得更加困难。
这更多是关于使用 Active Record 的问题,而不是针对 Eloquent 本身。支持和反对使用活动记录的争论有很多,我不会深入探讨。有关更多信息,我建议您阅读 Active Record(由 Eloquent 使用)、Data Mapper(由 Doctrine 使用)或更一般的 ORM 设计模式。