it-roy-ru.com

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

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

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

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

28
NAT3863

Разница между 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, когда мне нужно отфильтровать или найти данные в связанных таблицах. 

Дополнительная информация

document -> http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#joining-with-relations скажет вам следующее: 

"При работе с реляционными базами данных общая задача состоит в объединении нескольких таблиц и применении различных условий запроса и параметров к оператору SQL JOIN. Вместо явного вызова yii\db\ActiveQuery :: join () для создания JOIN запрос, вы можете повторно использовать существующие определения отношений и вызвать yii\db\ActiveQuery :: joinWith () для достижения этой цели. "

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

21
lin

joinWith использует JOIN для включения отношений в исходный запрос, а 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

33
topher

Обратите внимание, что в дополнение к вышеперечисленным отличным ответам, которые помогли мне понять, как использовать 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]);
0
Dhiraj Gupta