Laravel - 真的很难理解雄辩

Posted

技术标签:

【中文标题】Laravel - 真的很难理解雄辩【英文标题】:Laravel - Really struggling to understand eloquent 【发布时间】:2012-12-17 07:25:32 【问题描述】:

我是从 Codeigniter 过来的 Laravel 的新手,在很大程度上我真的很喜欢它,但我真的无法理解 Eloquent。

如果我想做一个这样的简单查询:

SELECT * FROM site INNER JOIN tweeter ON tweeter.id = site.tweeter_id

我尝试做这样的事情(带有“属于”):

$site = Site::with('tweeter')->find($site_id);

但现在我有两个查询和一个不需要的 IN(),如下所示:

SELECT * FROM `site` WHERE `id` = '12' LIMIT 1

SELECT * FROM `tweeter` WHERE `id` IN ('3')

所以我尝试像这样强制加入:

$site = Site::join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->find($site_id);

现在我收到这样的错误:

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous

SQL: SELECT * FROM `site` INNER JOIN `tweeter` ON `tweeter`.`id` = `site.tweeter_id` WHERE `id` = ? LIMIT 1

Bindings: array (
  0 => 12,
)

错误在哪里很明显,哪里需要使用“site.id = ?”之类的东西。但无论如何我都看不到要发生这种情况?

所以我只是坚持回到流利和使用:

DB::table('site')->join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->where('site.id','=',$site_id)->first()

我想这不是一个大问题。我真的很想理解雄辩。我不禁觉得我弄错了,误解了它的工作原理。我错过了什么吗?还是真的必须以非常特定的方式使用它?

我想我真正的问题是:有没有办法使用 Eloquent 进行我想要进行的查询?

【问题讨论】:

【参考方案1】:

您总是可以将 Eloquent 视为 Fluent 的扩展。

您遇到的问题是由 find() 命令引起的。它使用id 没有表名,这变得模棱两可。

这是一个记录在案的问题: https://github.com/laravel/laravel/issues/1050

要创建您正在寻找的命令,您可以这样做:

$site = Site::join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->where('site.id', '=', $site_id)->first($fields);

当然,您使用 join()->find() 的语法是正确的一旦采用该问题修复程序

【讨论】:

那么使用 eloquent 有什么意义呢?这是我不太明白的。 Eloquent 的新功能完全是多余的,我还不如直接用 Fluent。 Eloquent 是一个 ORM,因此您可以像访问虚拟数据库一样访问您的代码。当您管理关系而不是像这样使用联接时,Eloquent 更有意义。 Eloquent 还允许您进行预加载,从而减少对数据库的调用量。 另请注意,ORM 并非用于最佳 sql 查询实践。这适用于所有类型的 ORM。 我最初也有同样的想法。它看起来不同,但事实并非如此。你基本上有3层。 DB::query("select * from users")、DB::table('users') 和 User::find()。他们相互交替工作,以弥补对方的不足。 (例如,我的 Eloquent 全文搜索示例:gist.github.com/4199789)如果您像编写 SQL 一样进行编程,那么您将度过一段糟糕的时光。如果你用与另一个相关的所有东西来编程,这一切都很好,兄弟。 +1 对于@JoelLarson 所说的所有内容,除了他的最后一条评论。我不同意你说的方式。这实际上取决于正在执行的操作。有时,ORM 可以输出比你想写的更优化的查询。这实际上取决于许多不同的因素。不过,这里的信息应该很简单:不要依赖或期望 ORM 输出最佳查询。始终深入挖掘并弄清楚您从什么中抽象出来。【参考方案2】:

我实际上发现这种行为是有利的。考虑一下(我将修改您的示例)。所以我们有很多站点,每个站点都有很多高音扬声器。每个站点在数据库中都有很多信息:很多列,其中一些包含大量文本/数据的文本列。

您按照自己的方式进行查询:

SELECT * FROM site INNER JOIN tweeter ON tweeter.id = site.tweeter_id

有两个缺点:

    您会获得大量冗余数据。您为同一站点的高音扬声器获得的每一行都将具有您只需要一次的相同站点数据,因此 php 和您的数据库之间的通信需要更长的时间。 你如何处理 foreach (tweeter_of_this_site)?我猜你会在某种列表中显示所有站点,然后在每个站点中显示所有的高音扬声器。您必须编写一些自定义逻辑来执行此操作。

使用 ORM 方法解决了这两个问题:它只获取站点数据一次,并且允许您这样做:

foreach ($sites as $site) 
    foreach($site->tweeters as $tweeter) 

我还要说的是:不要打它!我曾经说过:我为什么要使用 ORM,我可以编写自己的 SQL,谢谢.现在我在 Laravel 中使用它,非常棒!

【讨论】:

以上是关于Laravel - 真的很难理解雄辩的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 雄辩的 ORM 关系

Laravel雄辩删除

Laravel 雄辩加入 ajax

Laravel 雄辩的极限查询

Laravel 4 雄辩的能力

Laravel - 雄辩的自我关系