Yii2中$ with和$ joinWith有什么区别?何时使用它们?

时间:2014-09-01 06:34:49

标签: php yii yii2

在API文档中指定了

  
      
  • $joinWith - 此查询应加入
  • 的关系列表   
  • $with - 此查询应与执行的关系列表
  •   

这些ActiveQuery属性与我们应该在什么情况下使用$joinWith$with有什么区别?

3 个答案:

答案 0 :(得分:34)

joinWith使用JOIN在原始查询中包含关系,而with则不包含。{/ p>

为了进一步说明,请考虑具有关系Post的课程comments,如下所示:

class Post extends \yii\db\ActiveRecord {
    ...
    public function getComments() {
        return $this->hasMany(Comment::className(), ['post_id' => 'id']);
    }
}

使用with以下代码:

$post = Post::find()->with('comments');

导致以下sql查询:

SELECT `post`.* FROM `post`;
SELECT `comment`.* FROM `comment` WHERE post_id IN (...)

下面是joinWith代码:

$post = Post::find()->joinWith('comments', true)

导致查询:

SELECT `post`.* FROM post LEFT JOIN `comment` comments ON post.`id` = comments.`post_id`;
SELECT `comment`.* FROM `comment` WHERE post_id IN (...);

因此,当使用joinWith时,您可以通过关系按/ filter / group排序。您可能必须自己消除列名称的歧义。

参考:http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#lazy-eager-loading

答案 1 :(得分:23)

withjoinWith

之间的差异

使用with方法会产生以下SQL查询

$users = User::find()->with('userGroup');

SELECT * FROM `user`;
SELECT * FROM `userGroup` WHERE userId = ...

...使用joinWith时将导致此SQL查询

$users = User::find()->joinWith('userGroup', true)

SELECT * FROM user LEFT JOIN `userGroup` userGroup ON user.`id` = userGroup.`userId`;

所以我需要在相关表格中过滤或搜索数据时使用joinWith

其他信息

docu - > http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#joining-with-relations会告诉你:

使用关系数据库时,常见的任务是连接多个表并将各种查询条件和参数应用于JOIN SQL语句。而不是显式调用yii \ db \ ActiveQuery :: join()来构建在JOIN查询中,您可以重用现有的关系定义并调用yii \ db \ ActiveQuery :: joinWith()来实现此目标。

这意味着,您现在可以自行处理joinsinnerJoinsouterJoins以及Yii2中所有相关的相关内容。 Yii(不是Yii2)仅使用join而不让用户决定加入类型。有关“加入”的详细信息 - >它是一个基于SQL的东西。你可以在这里阅读http://en.wikipedia.org/wiki/Join_(SQL)

答案 2 :(得分:1)

请注意,除了以上令人敬畏的答案,帮助我弄清楚如何使用joinWith(),每当你想使用joinWith()并且你有不明确的列名时,Yii / ActiveRecord自动似乎选择一个随机列,而不是你通常所期望的(最左边的表)。最好通过指定SELECT之类的内容在$query->select("post.*")子句中指定最左边的表。我从一些内部表中获取了id,并且它们被用尽了它们从最左边的表中 ,直到我想出来。

另一点需要注意的是,你可以为joinwith关系指定一个别名,所以你可以这样说:

$post->find()
->joinWith(["user u"])
->where(["u.id"=>$requestedUser->id])
->select("post.*")
->orderBy(["u.created_at"=>SORT_DESC]);