Changes
Title
changed
Relational Query - Lazy Loadning and Eager Loading in Yii 2.0
Category
unchanged
Tutorials
Yii version
changed
2.0
Tags
changed
relational query, lazyeager loading, eagerlazy loading, with, join, joinWith
Content
changed
It's well known that there are **Lazy Loading** approach and **Eager Loading** approach in the relational query. But it's very important to know how the Eager Loading approach works in Yii 2
, since i. It has changed drastically from that of Yii 1.1
, and there are common misunderstandings about it in the community.
In the following sections, we assume an example of 1:N relation like this:[...]
- An Author has_many Posts
```php
/* Author.php */
public function getPosts()[...]
- A Post has_one Author
```php
/* Post.php */
public function getAuthor()[...]
The following is an example of lazy loading.
```php
$authors = Author::find()->all(); // fetches only the authors
foreach($authors as $author) {[...]
The following is an example of eager loading.
```php
$authors = Author::find()->with('posts')->all(); // fetches the authors with their posts
foreach($authors as $author) {[...]
"It's more effective, isn't it?"
Yes, it looks more effective, and actually it is sometimes. In fact, Yii 1.1
did havehad this single query approach using JOIN, along with the multiple query approach without JOIN.
But the single query approach has a fatal drawback when you want to use **LIMIT** and/or **OFFSET**.[...]
Imagine you wanted to list 10 authors with their posts. You would write like this:
```php
$authors = Author::find()->with('posts')->limit(10)->all();
```[...]
Although it will fetch 10 rows, it doesn't mean 10 authors since every author can have multiple posts.
So, considering this, that and the other,Among other major reasons that the developers have considered is that a relation between relational db and NOSQL db can be easily implemented with the separated query approach. And **Yii 2 has discarded the single query approach for the Eager Loading**. Please remember, in Yii 2, **the related models are always fetched with a separated query**.
What join and joinWith Do?[...]
For example, when you want to list authors who have at least one post with a title containing some key word, you can write like the following using 'leftJoin':
```php
$authors = Author::find()
->leftJoin('post', ['post.author_id' => 'author.id']) // the table name and the condition for 'ON'[...]
So, probably you may want to use 'joinWith' like the following:
```php
$authors = Author::find()
->joinWith('posts') // the relation name
->where(['like', 'post.title', $keyword])
->all();
foreach($authors as $author) {[...]