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

Php Yii2中的$with和$joinWith有什么区别?何时使用它们?,php,yii,yii2,Php,Yii,Yii2,API文档中规定: $joinWith-此查询应与之连接的关系列表 $with-此查询应执行的关系列表 这些ActiveQuery属性之间有什么区别?在什么情况下我们应该使用$joinWith和$with?与和joinWith之间的区别 将与方法一起使用会产生以下SQL查询 $users = User::find()->with('userGroup'); SELECT * FROM `user`; SELECT * FROM `userGroup` WHERE userId = .

API文档中规定:

  • $joinWith
    -此查询应与之连接的关系列表
  • $with
    -此查询应执行的关系列表
这些ActiveQuery属性之间有什么区别?在什么情况下我们应该使用
$joinWith
$with

joinWith
之间的区别 将
方法一起使用会产生以下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

附加信息 ->将告诉您:

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


也就是说,您现在可以自己处理Yii2中的
连接
内部连接
外部连接
以及所有相关的好东西Yii(不是Yii2)只使用
join
,而不让用户决定join的类型。关于“Join’s”的详细信息->它是一个基于SQL的东西。您可以在这里了解这一点

joinWith
使用
JOIN
将关系包括在原始查询中,而
with
则不包括

进一步说明,考虑类<代码> POST <代码>,关系>代码>注释< /代码>如下:

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

$post = Post::find()->with('comments');
$post = Post::find()->joinWith('comments', true)
导致以下sql查询:

SELECT `post`.* FROM `post`;
SELECT `comment`.* FROM `comment` WHERE post_id IN (...)
鉴于
与下面的
代码连接:

$post = Post::find()->with('comments');
$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
时,您可以按关系排序/筛选/分组。您可能需要自己消除列名的歧义


参考资料:

请注意,除了上述帮助我了解如何使用
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]);

joinWith
仍然会导致两个查询…出于我不太理解的原因…我一直理解“SQL查询越少越好”因此,
joinWith
只有在查询相关表中的列时才有用,否则这只是一个缺点。SQL查询越少越好,这并不一定是真的。这取决于列的索引程度。带
joinWith
之间的最大区别在于巨大的数据量ets-例如,在两个表之间连接数百万条记录比在索引列上进行简单子查询(实际上是两个简单查询)要密集得多的操作。因此,在这种情况下,将simpler
一起使用很可能是更好的选择。@存储代码尝试将acquiredLoading设置为false。这必须使它只执行一个查询,而不是两个查询。