Жадібне завантаження в Yii2, для тих хто хоче зрозуміти що це таке

Пост розповідає для чого необхідно використовувати «жадібне завантаження», замість «ледачою завантаження», не претендує на ідеал. І навряд чи зацікавить професіоналів, більше підходить для початківців у вивченні YII2.

Використовуємо жадібне завантаження в своєму додатку. Припустимо у нас є дві таблиці з постами і категоріями. У кожного поста можлива одна категорія, у категорій 1 або більше постів.

bd - mediarise.ru


Припустимо ми скрудили моделі, контролери, подання з цих таблиць. Заповнимо список постів. Зверніть увагу, у колонці категорій відображаються самі назви категорій, а не id категорій.

bd - mediarise.ru

Відобразити назву категорій можна представлення: «views/post/index.php» змінивши GridView таким чином:

<?php ...
use app\models\Category;
?>

<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],

'id',
[
'attribute' => 'category_id',
'filter' => Category::find()->select(['name', 'id'])->indexBy('id')->column(),
'value' => 'category.name',
],
'name',
'content:n-текст',

['class' => 'yii\grid\ActionColumn'],
],
]); ?>

// 'attribute' => 'category_id', до атрибуту category_id, додаємо значення 'value' => 'category.name', де name якраз після з назвою категорії
// 'filter' => Category::find()->select(['name', 'id'])->indexBy('id')->column(), -- дає змогу фільтрувати назва категорій
// 'value' => 'category.name',



От як раз, тут нам і знадобиться «жадібне завантаження». Справа в тому, що якщо ми подивимося sql — запити нашої програми.

bd - mediarise.ru

Ми побачимо безліч запитів з таблиці category, такого виду
SELECT * FROM `sb_category` WHERE `id`=x


Де x — id з постів — category_id. Якщо у нас буде виводиться на сторінці 100, 500, 1000 постів, буде і стільки ж вибірок в таблиці post. В даному випадку, якщо подивитися по часу виконання скрипта, запити в БД виконуються швидко. Але якщо ми можемо заощадити ресурси, чому б цим не скористатися. Для цього створена «жадібне завантаження». Жадібне завантаження, це завантаження з надлишковими даними, як би з приєднаною таблицею.

У моделі app\models\PostSearc, в методі search, додамо жадібне завантаження через метод with

public function search($params)
{
$query = Post::find();


public function search($params)
{
$query = Post::find()->with(['category']);


Після цього дивимося на результат:

bd - mediarise.ru

Зараз ми бачимо, замість численних запитів до БД, ми отримуємо лише 2. Вибірку даних з таблиць psot і category.
Метод with збирає всі поля category_id з таблиці post, і робить один запит до БД, витягуючи всі категорії по умові WHERE `id` IN (1, 2, 3, 4, 5). Тобто в where перераховуються всі id, які є в першій вибірці post
SELECT * FROM `sb_post` LIMIT 20


Для того що б працювала фільтрація, сортування в GridView. Необхідно замість with(), використовувати joinWith().
joinWith() виконує жадібне завантаження і приєднує додаткову таблицю з допомогою join і це дає нам можливість додавати умови, сортування.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.