В чем разница между $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]);