【问题标题】:How come "with" results in multiple queries in Eloquent在 Eloquent 中,“with”如何导致多个查询
【发布时间】:2019-11-07 18:08:23
【问题描述】:

从这里: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

【问题讨论】:

  • 建议查询的一大缺点:同名的列会相互覆盖。在您的情况下,结果将有一个 id 列,其值将来自 profiles(最后一个表)。

标签: laravel eloquent laravel-5.8


【解决方案1】:

它仍然比延迟加载好得多,这意味着每个查询都是分开的。

你的期望不会像你想的那样奏效。您可以使用 join 代替。

类似这样的:

\DB::table('posts as p')
    ->join('authors as a', 'p.author_id', '=', 'a.id')
    ->join('profiles as pr', 'pr.id', '=', 'a.profile_id')
    ->get();

【讨论】:

    【解决方案2】:

    Eloquent 执行这样的查询,因此它可以为每一行数据建立一个单独的模型。这对于在加载模型后启用其他 Eloquent 功能非常重要。通过急切加载,数字查询始终是可预测的。 App\Post::with('author.profile')->get(); 将始终执行三个查询,无论帖子、作者或个人资料的数量如何。如果没有预先加载,它将根据返回的记录数以指数方式运行更多查询。这是 Eloquent 实现 Active Record 设计模式的结果。

    查询数据的“更清洁”方式的示例本质上是进行连接。您可以使用联接在一个查询中获取各种关系的所有数据。在 Laravel 上下文中的缺点是所有数据都将存在于 Post 模型中,即使它来自三个不同的表。如果您只想快速显示所有数据,这很好,但在尝试操作和更新数据时变得更加困难。

    这更多是关于使用 Active Record 的问题,而不是 Eloquent 本身的问题。有很多支持和反对使用主动记录的论据,我不会讨论。有关更多信息,我建议您阅读 Active Record(由 Eloquent 使用)、Data Mapper(由 Doctrine 使用)或更一般的 ORM 设计模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多