Kali ini kita belajar mengenai ActiveRecord pada Yii, terutama yang berkaitan dengan relasi. Dalam hal memanggil data relasi yang ada pada tabel lain, ada istilah lazy loading dan eager loading. Lazy loading, sesuai namanya yang berarti malas, relasinya hanya dipanggil ketika nanti dibutuhkan. Sementara pada eager loading, sesuai namanya yang berarti bersemangat, data relasinya sudah disiapkan untuk mengantisipasi jika nanti ada yang me-request datanya.
Sekarang kita ambil sebuah kasus relasi antara pengarang dan tulisannya (relasi one-to-many). Pengarang kita buatkan tabel author dan tulisannya kita simpan pada tabel post. Dari kedua tabel tersebut kita membuat dua buah model Author dan Post.
Pada model author, kita buat relasinya seperti ini:
Pada model Post kita buat relasinya seperti ini:
Untuk contoh lazy loading, kodenya adalah seperti ini:
Sementara jika kita menerapkan eager loading, sintaksnya menjadi seperti ini:
Pada cara eager loading di atas, sebenarnya kueri yang dijalankan ada dua, yaitu:
Jika Anda ingin cukup satu kueri saja, gunakan fungsi joinWith('nama_field_relasi') sebagai pengganti fungsi with:
Nah, contoh di atas menggunakan joinWith yang ternyata punya kelemahan jika kita ingin menggunakan LIMIT.
Contoh sintaks:
Sintaks tersebut akan menjalankan dua buah kueri berikut:
Lain halnya kalau kita menggunakan join, tentu limit yang dimunculkan adalah baris teratas sebatas limit, dengan kueri kira-kira seperti ini:
Demikian, semoga bermanfaat dan selamat belajar!
Referensi:
Sekarang kita ambil sebuah kasus relasi antara pengarang dan tulisannya (relasi one-to-many). Pengarang kita buatkan tabel author dan tulisannya kita simpan pada tabel post. Dari kedua tabel tersebut kita membuat dua buah model Author dan Post.
Pada model author, kita buat relasinya seperti ini:
/* Author.php */ //nama field relasinya adalah posts, dari nama fungsi getPosts public function getPosts() { return $this->hasMany(Post::className(), ['author_id' => 'id']); }
Pada model Post kita buat relasinya seperti ini:
/* Post.php */ //nama field relasinya adalah author, dari nama fungsi getAuthor public function getAuthor() { return $this->hasOne(Author::className(), ['id' => 'author_id']); }
Untuk contoh lazy loading, kodenya adalah seperti ini:
$authors = Author::find()->all(); // mengambil hanya data dari tabel author foreach($authors as $author) { echo "<h2>Author : " . $author->name . "</h2>"; echo "<ul>"; foreach($author->posts as $post) { // memanggil data post satu per satu (queri lagi) echo "<li>" . $post->title . "</li>"; } echo "</ul>"; }
Sementara jika kita menerapkan eager loading, sintaksnya menjadi seperti ini:
// memanggil data author sekaligus post dengan fungsi with('nama_field_relasi') $authors = Author::find()->with('posts')->all(); foreach($authors as $author) { echo "<h2>Author : " . $author->name . "</h2>"; echo "<ul>"; foreach($author->posts as $post) { // tak ada query lagi echo "<li>" . $post->title . "</li>"; } echo "</ul>"; }
Pada cara eager loading di atas, sebenarnya kueri yang dijalankan ada dua, yaitu:
SELECT * FROM author; SELECT * FROM post WHERE author_id IN (1, 3, 7, 10, ... X);
Jika Anda ingin cukup satu kueri saja, gunakan fungsi joinWith('nama_field_relasi') sebagai pengganti fungsi with:
$authors = Author::find() ->joinWith('posts') // nama field relasi ->where(['like', 'post.title', $keyword]) ->all(); foreach($authors as $author) { echo "<h2>Author : " . $author->name . "</h2>"; echo "<ul>"; foreach($author->posts as $post) { // tidak perlu kueri lagi echo "<li>" . $post->title . "</li>"; } echo "</ul>"; }
Nah, contoh di atas menggunakan joinWith yang ternyata punya kelemahan jika kita ingin menggunakan LIMIT.
Contoh sintaks:
$authors = Author::find()->with('posts')->limit(10)->all();
Sintaks tersebut akan menjalankan dua buah kueri berikut:
SELECT * FROM author LIMIT 10; SELECT * FROM post WHERE author_id IN (1, 3, 7, 10, ... X);
Lain halnya kalau kita menggunakan join, tentu limit yang dimunculkan adalah baris teratas sebatas limit, dengan kueri kira-kira seperti ini:
SELECT * FROM author JOIN post ON post.author_id = author.id LIMIT 10;
Demikian, semoga bermanfaat dan selamat belajar!
Referensi:
- http://www.yiiframework.com/wiki/834/relational-query-lazy-loadnig-and-eager-loading-in-yii-2-0/
Tidak ada komentar:
Posting Komentar