В чем разница между $with и $joinWith в Yii2 и когда их использовать?

в документации API указано, что

  • $joinWith - список отношений, которые этот запрос должен быть присоединился С
  • $with - список отношений, которые этот запрос должен быть выполненного С

в чем разница между этим свойством ActiveQuery и в какой ситуации мы должны использовать $joinWith и $with?

3 ответов


разницу между with и joinWith

используя 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() для создания запроса соединения можно повторно использовать существующие определения отношений и вызвать yii\db\ActiveQuery::joinWith() для достижения эта цель."

что означает, что вы в состоянии справиться joins, innerJoins, outerJoins и все хорошие связанные вещи в Yii2 самостоятельно. Yii (не Yii2) использует только join вместо не позволяя пользователю решать о типе соединения. Подробности о "Join's" - > его вещь на основе SQL. Вы можете прочитать об этом здесь http://en.wikipedia.org/wiki/Join_ (SQL)


joinWith использует JOIN чтобы включить отношения в исходный запрос while with нет.

чтобы проиллюстрировать Далее, рассмотрим класс 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


обратите внимание, что в дополнение к выше удивительным ответам, которые помогли мне понять, как использовать joinWith(), что всякий раз, когда вы хотите использовать joinWith() и у вас есть неоднозначные имена столбцов, Yii / ActiveRecord автоматически выбирает случайный столбец вместо того, что вы обычно ожидаете (крайняя левая таблица). Лучше всего указать крайнюю левую таблицу в SELECT п., указав что-то вроде $query->select("post.*"). Я получал идентификаторы от некоторых внутренних таблиц, и они использовались, как они были от самого левого стола, пока я не понял это.

еще один момент, чтобы отметить, что вы можете укажите псевдоним для связи joinwith, чтобы вы могли сказать что-то вроде:

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