start-databases.md 15.1 KB
Newer Older
RichWeber committed
1
Робота з базами даних
2
=====================
RichWeber committed
3

4 5 6
Цей розділ описує, як створити нову сторінку, яка буде відображати дані країни, отримані з таблиці бази даних `country`.
Для цього, вам необхідно буде налаштувати зʼєднання з базою даних, створити клас [Active Record](db-active-record.md), 
визначити [дію](structure-controllers.md) та створити [представлення](structure-views.md).
RichWeber committed
7

8
За допомогою даного посібника ви дізнаєтесь як:
RichWeber committed
9

10
* Налаштувати зʼєднання з базою даних
RichWeber committed
11
* Оголосити Active Record класс
12 13
* Запитувати дані за допомогою класу Active Record
* Відображати дані у представленні із розбиттям по сторінках
RichWeber committed
14

15 16
Зверніть увагу, що для того, щоб закінчити цей розділ, ви повинні мати базові знання і досвід використання баз даних. 
Зокрема, ви повинні знати, як створювати бази даних, як виконувати SQL-запити за допомогою клієнтських додатків баз даних.
RichWeber committed
17 18 19


Підготовка бази даних <a name="preparing-database"></a>
20
---------------------
RichWeber committed
21

22 23 24
Для початку, створіть базу даних `yii2basic`, з якої і будете надалі отримувати дані. 
Ви можете використовувати SQLite, MySQL, PostgreSQL, MSSQL або Oracle бази даних, Yii має вбудовану підтримку для багатьох баз даних.
Для простоти, будемо вважати що використовується MySQL у подальшому описі.
RichWeber committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

Далі, створіть таблицю `country`, і внесіть декілька прикладів. Можете використати наступний SQL-запит, як приклад:

```sql
CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `country` VALUES ('AU','Australia',18886000);
INSERT INTO `country` VALUES ('BR','Brazil',170115000);
INSERT INTO `country` VALUES ('CA','Canada',1147000);
INSERT INTO `country` VALUES ('CN','China',1277558000);
INSERT INTO `country` VALUES ('DE','Germany',82164700);
INSERT INTO `country` VALUES ('FR','France',59225700);
INSERT INTO `country` VALUES ('GB','United Kingdom',59623400);
INSERT INTO `country` VALUES ('IN','India',1013662000);
INSERT INTO `country` VALUES ('RU','Russia',146934000);
INSERT INTO `country` VALUES ('US','United States',278357000);
```

RichWeber committed
47
На даний момент, у вас є база даних `yii2basic` і таблиця `country` з трьома колонками, що містять десять рядків даних.
RichWeber committed
48 49

Налаштування підключення до БД <a name="configuring-db-connection"></a>
50
------------------------------
RichWeber committed
51

52 53
Перш ніж продовжити, переконайтеся, що у вас налаштовано [PDO](http://www.php.net/manual/en/book.pdo.php) PHP розширення 
і PDO драйвер для вашої БД (наприклад `pdo_mysql` для MySQL). Це є основною вимогою, якщо ваш додаток використовує реляційну базу даних.
RichWeber committed
54

55 56
Згідно того, що у вас встановлено, відкрийте файл `config/db.php` і замініть на коректні дані вашої БД.
За замовчуванням, файл містить наступне:
RichWeber committed
57 58 59 60 61 62 63 64 65 66 67 68 69

```php
<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];
```

70 71 72
Файл конфігурації `config/db.php` є типовим інструментом [налаштування](concept-configurations.md) на основі файлів. 
Даний файл конфігурації визначає параметри, які необхідні для створення і ініціалізації [[yii\db\Connection]] примірника,
через який ви можете робити SQL-запити до основної бази даних.
RichWeber committed
73

74
З’єднання з БД, описане вище, може бути доступне в коді додатка за допомогою виразу `Yii::$app->db`.
RichWeber committed
75

76 77 78
> Інформація: Файл конфігурації `config/db.php` буде включений до конфігурації головного додатка `config/web.php`, 
  який визначає як має бути проініційований сам [додаток](structure-applications.md). Для отримання додаткової інформації, 
  будь ласка, зверніться до розділу [Налаштування](concept-configurations.md).
RichWeber committed
79 80 81


Створення Active Record <a name="creating-active-record"></a>
82
-----------------------
RichWeber committed
83

84 85
Для відображення і отримання даних з таблиці `country` створіть [Active Record](db-active-record.md) клас 
з іменем `Country`, і збережіть в файл `models/Country.php`.
RichWeber committed
86 87 88 89 90 91 92 93 94 95 96 97 98

```php
<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}
```

99 100
Клас `Country` наслідує [[yii\db\ActiveRecord]]. Вам не потрібно писати ніякого коду всередині нього! 
Всього лише за допомогою описаного вище коду, Yii самостійно вгадає відповідне імʼя таблиці з імені класу.
RichWeber committed
101

102 103
> Інформація: Якщо немає прямого співпадіння з імені класу і таблиці, 
  ви можете використати метод [[yii\db\ActiveRecord::tableName()]] щоб задати відповідне імʼя таблиці.
RichWeber committed
104

RichWeber committed
105
Використовуючи клас `Country`, ви можете легко маніпулювати даними з таблиці `country`, як показано в наступному фрагменті:
RichWeber committed
106 107 108 109

```php
use app\models\Country;

110
// отримати всі рядки з таблиці country і відсортувати їх по "name"
RichWeber committed
111 112 113 114 115 116 117 118 119 120 121 122 123
$countries = Country::find()->orderBy('name')->all();

// отримати рядок, по основному ключу "US"
$country = Country::findOne('US');

// відобразити "United States"
echo $country->name;

// оновити назву країни на "U.S.A." і зберегти в БД
$country->name = 'U.S.A.';
$country->save();
```

124 125 126
> Інформація: Active Record є потужним засобом для доступу і управління даними в базі даних в обʼєктно-орієнтованому стилі.
  Ви можете знайти більш детальну інформацію в розділі [Active Record](db-active-record.md). Крім того, ви також можете 
  взаємодіяти з базою даних, використовуючи для доступу метод передачі даних нижнього рівня під назвою [Data Access Objects](db-dao.md).
RichWeber committed
127 128


129 130
Створення дії <a name="creating-action"></a>
-------------
RichWeber committed
131

132 133 134
Щоб відобразити дані про країну кінцевим користувачам, необхідно створити нову дію. Замість розміщення нової дії 
у контролері `site`, який ви використовували в попередніх розділах, є сенс створити новий контролер спеціально для всіх дій, 
пов’язаних з даними країн. Створіть новий контролер з іменем `CountryController` і дію `index`, як показано нижче:
RichWeber committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

```php
<?php

namespace app\controllers;

use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}
```

Збережіть цей код у файл `controllers/CountryController.php`.

171 172 173
Дія `index` викликає метод `Country::find()`. Цей метод Active Record будує запит бази даних і отримує всі дані з таблиці `country`.
Щоб обмежити кількість країн, які будуть отримуватись в кожному запиті, сам запит розбивається на сторінки, за допомогою об’єкта
[[yii\data\Pagination]]. Об’єкт `Pagination` служить двом цілям:
RichWeber committed
174

175 176 177 178
* Встановлює `offset` і `limit` для SQL-запиту так, щоб він повертав лише одну сторінку даних за один раз 
  (не більше 5 рядків на сторінці).
* Використовується у представленнях для відображення пейджера, який складається із переліку кнопок переходу по сторінкам,
  про що буде описано у наступному підрозділі.
RichWeber committed
179

180
Наприкінці, дія `index` повертає представлення `index` і передає дані по країнах, з розбивкою на сторінки.
RichWeber committed
181 182 183


Створення представлення <a name="creating-view"></a>
184
-----------------------
RichWeber committed
185

186 187
В директорії `views` створіть спочатку підкаталог `country`. Цей каталог буде використовуватись для всіх представленнь 
контролера `country`. В каталозі `views/country`, створіть файл з іменем`index.php` що містить наступне:
RichWeber committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

```php
<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Країни</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->name} ({$country->code})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>
```

207 208 209 210
Дане представлення містить два розділи для відображення даних по країнам. У першій частині, відображаються дані про країни 
у вигляді невпорядкованого списку HTML. У другій частині, [[yii\widgets\LinkPager]] віджет з використанням інформації 
про нумерацію сторінок. Віджет `LinkPager` відображаться у вигляді переліку кнопок. 
При натисканні на будь-якій з них будуть оновлюватись дані країн на відповідній сторінці.
RichWeber committed
211 212 213


Спробуєм <a name="trying-it-out"></a>
214
--------
RichWeber committed
215 216 217 218 219 220 221

Щоб побачити все, що було створено під час роботи, відкрийте в браузері наступний URL:

```
http://hostname/index.php?r=country/index
```

222
![Перелік країн](images/start-country-list.png)
RichWeber committed
223

224 225
Спочатку, ви побачите сторінку з переліком пʼяти країн. Нижче країн, ви побачите пейджер з чотирма кнопками. 
Якщо ви натиснете на кнопку "2", ви побачите сторінку з іншими пʼятьма країнами з бази даних: другу сторінку записів. 
RichWeber committed
226 227 228 229 230 231
Придивившись більш уважно, ви побачите, що URL в браузері також змінюється на

```
http://hostname/index.php?r=country/index&page=2
```

232
За лаштунками, [[yii\data\Pagination|Pagination]] надає всю необхідну функціональність для розбиття набору даних на сторінки:
RichWeber committed
233

234 235 236 237 238
* Спочатку, [[yii\data\Pagination|Pagination]] представляє першу сторінку, яка відображає країни запитом SELECT 
  з умовою `LIMIT 5 OFFSET 0`. В результаті, будуть відображені перші знайдені пʼять країн.
* [[yii\widgets\LinkPager|LinkPager]] віджет відображає кнопки сторінок з URL-адресами створеними за допомогою 
  [[yii\data\Pagination::createUrl()|Pagination]]. URL-адреси будуть містити параметр запиту `page`, 
  який представляє різні номери сторінок.
RichWeber committed
239
* Якщо ви натиснете кнопку "2", спрацює новий запит, який буде відправлений на `country/index` з подальшим опрацюванням.
RichWeber committed
240
  [[yii\data\Pagination|Pagination]] зчитає параметр `page` з URL-запиту і встановить номер поточної сторінки в 2-ку.
241
  Таким чином, новий запит буде мати визначення `LIMIT 5 OFFSET 5` і поверне наступні пʼять країн для відображення.
RichWeber committed
242 243


244 245
Підсумок <a name="summary"></a>
--------
RichWeber committed
246

247 248
В цьому розділі ви дізналися, як працювати з базою даних. Ви також дізналися, як вибирати і відображати дані на сторінках 
за допомогою [[yii\data\Pagination]] і [[yii\widgets\LinkPager]].
RichWeber committed
249

250 251 252 253
У наступному розділі ви дізнаєтеся, як використовувати потужний інструмент генерації коду, що називається [Gii](tool-gii.md), 
який допоможе вам швидко здійснювати деякі часто необхідні функції, такі як Create-Read-Update-Delete (CRUD) 
операції для роботи з даними в таблицях баз даних. 
Насправді, код, який ви щойно написали, Yii може автоматично сгенерувати з допомогою функції Gii.