Побудовані поверх PDO. Yii DAO (об'єкти доступу до даних) забезпечують об'єктно-орієнтована API для доступу до реляційних баз даних. Це основа для інших, більш просунутих, методів доступу до баз даних, включаючи будівник запитів і active record.
При використанні Yii DAO ви в основному будете використовувати чистий SQL і масиви PHP. Як результат, це найефективніший спосіб доступу до баз даних. Проте, так як синтаксис SQL може відрізнятися для різних баз даних, використовуючи Yii DAO вам потрібно буде докласти додаткових зусиль, щоб зробити додаток не залежних від конкретної бази даних.
Yii DAO з коробки підтримує наступні бази даних:
Note: Нова версія pdo_oci для PHP 7 на даний момент існує тільки у формі вихідного коду. Використовуйте інструкції спільноти по компіляції.
Створення підключення до бази даних
Для доступу до бази даних, ви спочатку повинні підключиться до неї, створивши екземпляр класу yii \ db \ Connection:
Так як підключення до БД часто потрібно в кількох місцях, поширеною практикою є його настройка як компонента програми:
Тепер ви можете отримати доступ до підключення до БД за допомогою виразу Yii :: $ app-> db.
Tip: Ви можете налаштувати декілька компонентів підключення, якщо в вашому додатку використовується кілька баз даних.
Під час налаштування підключення, ви повинні обов'язково вказувати Ім'я Джерела Даних (DSN) через параметр dsn. Формат DSN відрізняється для різних баз даних. Додатковий опис дивіться в довіднику PHP. Нижче представлені кілька прикладів:
- MySQL, MariaDB: mysql: host = localhost; dbname = mydatabase
- SQLite: sqlite: / path / to / database / file
- PostgreSQL: pgsql: host = localhost; port = 5432; dbname = mydatabase
- CUBRID: cubrid: dbname = demodb; host = localhost; port = 33000
- MS SQL Server (via sqlsrv driver): sqlsrv: Server = localhost; Database = mydatabase
- MS SQL Server (via dblib driver): dblib: host = localhost; dbname = mydatabase
- MS SQL Server (via mssql driver): mssql: host = localhost; dbname = mydatabase
- Oracle: oci: dbname = // localhost: одна тисяча п'ятсот двадцять один / mydatabase
Зауважте, що якщо ви підключаєтеся до бази даних через ODBC, вам необхідно вказати властивість yii \ db \ Connection :: driverName. щоб Yii знав який тип бази даних використовується. наприклад,
Крім властивості dsn. вам необхідно вказати username і password. Дивіться yii \ db \ Connection для того, щоб подивитися повний список властивостей.
Info: При створенні екземпляра з'єднання до БД, фактичне з'єднання з базою даних буде встановлено тільки при виконанні першого SQL запиту або при явному виклику методу open ().
Tip: Іноді може знадобитися виконати деякі запити відразу після з'єднання з базою даних, для ініціалізації змінних оточення. Наприклад, щоб задати часовий пояс або кодування. Зробити це можна зареєструвавши обробник для події afterOpen в конфігурації програми:
Виконання SQL запитів
Після створення екземпляра з'єднання, ви можете виконати SQL запит, виконавши наступні кроки:
- Створити yii \ db \ Command з запиту SQL;
- Прив'язати параметри (не обов'язково);
- Викликати один з методів виконання SQL з yii \ db \ Command.
Наступний приклад показує різні способи отримання даних з бази динних:
Note: Щоб зберегти точність, дані витягуються як рядки, навіть якщо тип поля в базі даних є числовим.
прив'язка параметрів
При створенні команди з SQL запиту з параметрами, ви майже завжди повинні використовувати прив'язку параметрів для запобігання атак через SQL ін'єкції. наприклад,
У SQL запит, ви можете вбудовувати один або кілька маркерів (наприклад: id в прикладі вище). Маркери повинні бути рядком, що починається з двокрапки. Далі вам потрібно викликати один з наступних методів для прив'язки значень до параметрів:
- bindValue (). прив'язка одного параметра за значенням
- bindValues (). прив'язка декількох параметрів в одному виклику
- bindParam (). схоже на bindValue (). але прив'язка відбувається за посиланням.
Наступний приклад показує альтернативний шлях прив'язки параметрів:
Прив'язка змінних реалізована через підготовлювані запити. Крім запобігання атак шляхом SQL ін'єкцій, це збільшує продуктивність, так як запит готується один раз, а потім виконується багато разів з різними параметрами. наприклад,
Так як bindParam () підтримує прив'язку параметрів по посиланню, наступний код може бути написаний таким чином:
Зверніть увагу що ви пов'язуєте маркер $ id зі змінною перед виконанням запиту, і потім міняєте це значення перед кожним наступним виконанням (часто це робиться в циклі). Виконанні запитів таким чином може бути значно більш ефективним, ніж виконання запиту для кожного значення параметра.
Виконання Ні-SELECT запитів
У методах queryXyz (). описаних в попередніх розділах, викликаються SELECT запити для отримання даних з бази. Для запитів які не повертають дані, ви повинні використовувати метод yii \ db \ Command :: execute (). наприклад,
Метод yii \ db \ Command :: execute () повертає кількість рядків оброблених SQL запитом.
Для запитів INSERT, UPDATE і DELETE, замість написання чистого SQL, ви можете викликати методи insert (). update (). delete (). відповідно, для створення зазначених SQL конструкцій. наприклад,
Ви можете також викликати batchInsert () для вставки безлічі рядків за один виклик. Це більш ефективно ніж вставляти записи по одній за раз:
Зверніть увагу, що перераховані методи лише створюють запит. Щоб його виконати потрібно викликати execute ().
Екранування імен таблиць і стовпців
При написанні незалежного від бази даних коду, правильно екранувати імена таблиць і стовпців досить важко, так як в різних базах даних правила екранування різні. Щоб подолати цю проблему ви можете використовувати наступний синтаксис екранування використовується в Yii:
- [[Column name]]. укладайте ім'я стовпця в подвійні квадратні дужки;
- >. укладайте ім'я таблиці в подвійні фігурні дужки.
Yii DAO буде автоматично перетворювати подібні конструкції в SQL в правильно екрановані імена таблиць і стовпців. наприклад,
Використання префіксів таблиць
Якщо більшість ваших таблиць використовує загальний префікс в імені, ви можете використовувати властивість Yii DAO для вказівки префікса.
Перш за все, вкажіть префікс таблиць через властивість yii \ db \ Connection :: $ tablePrefix:
Потім в коді, коли вам потрібно посилатися на таблицю, ім'я якої містить такий префікс, використовуйте синтаксис>. Символ відсотка буде автоматично замінений на префікс таблиці, яку вказує користувач під час конфігурації з'єднання з базою даних. наприклад,
виконання транзакцій
Коли ви виконуєте кілька залежних запитів послідовно, вам може знадобитися обернути їх в транзакцію для забезпечення цілісності вашої бази даних. Якщо в будь-якому з запитів відбудеться помилка, база даних відкотиться на стан, який був до виконання запитів.
Наступний код показує типове використання транзакцій:
Код вище еквівалентний наведеним нижче. Різниця в тому, що в даному випадку ми отримуємо більше контролю над обробкою помилок:
Note: в коді вище заради сумісності з PHP 5.x і PHP 7.x використані два блоку catch. \ Exception реалізує інтерфейс \ Throwable interface починаючи з PHP 7.0. Якщо ви використовуєте тільки PHP 7 і новіше, можете пропустити блок з \ Exception.
При виклику методу beginTransaction (). буде запущена нова транзакція. Транзакція представлена об'єктом yii \ db \ Transaction збереженим в змінній $ transaction. Потім, запити будуть виконуватися в блоці try. catch. Якщо запити будуть виконані вдало, буде виконаний метод commit (). Інакше, буде викликано виключення, і буде викликаний метод rollBack () для відкату змін зроблених до невдало виконаного запиту в транзакції.
Вказівка рівня ізоляції
Yii підтримує настройку [рівня ізоляції] для ваших транзакцій. За замовчуванням, при старті транзакції, буде використаний рівень ізоляції налаштований у вашій базі даних. Ви можете перевизначити рівень ізоляції за замовчуванням, як зазначено нижче:
Yii надає чотири константи для найбільш поширених рівнів ізоляції:
Крім використання наведених вище констант для завдання рівня ізоляції, ви можете, також, використовувати рядки підтримувані вашої СУБД. Наприклад, в PostgreSQL, ви можете використовувати SERIALIZABLE READ ONLY DEFERRABLE.
Зауважте що деякі СУБД допускають налаштовувати рівень ізоляції тільки для всього з'єднання. Наступні транзакції будуть отримувати той же рівень ізоляції, навіть якщо ви його не вкажете. При використанні цієї функції може знадобитися встановити рівень ізоляції для всіх транзакцій, щоб уникнути явно конфліктуючих налаштувань. На момент написання цієї статті страждали від цього обмеження тільки MSSQL і SQLite.
Note: SQLite підтримує тільки два рівня ізоляції, таким чином ви можете використовувати тільки READ UNCOMMITTED і SERIALIZABLE. Використання інших рівнів ізоляції призведе до генерації виключення.
Note: PostgreSQL не допускає установки рівня ізоляції до старту транзакції, так що ви не зможете встановити рівень ізоляції прямо при старті транзакції. Ви можете використовувати yii \ db \ Transaction :: setIsolationLevel () в такому випадку після старту транзакції.
вкладені транзакції
Якщо ваша СУБД підтримує Savepoint, ви можете вкладати транзакції як показано нижче:
Реплікація і поділ запитів на читання і запис
Багато СУБД підтримують реплікацію баз даних для кращої доступності бази даних і зменшення часу відповіді сервера. З репликацией бази даних, дані копіюються з master servers на slave servers. Всі вставки і оновлення має відбуватися на основному сервері, хоча читання може здійснюватися і з підлеглих серверів.
Щоб скористатися перевагами реплікації і досягти поділу читання і запису, вам необхідно налаштувати компонент yii \ db \ Connection як зазначено нижче:
Вищевказана конфігурація визначає систему з одним майстром і кількома підлеглими. Один з підлеглих буде підключений і використаний для читання, в той час як майстер буде використовуватися для запитів записи. Такий поділ читання і запису буде здійснено автоматично з вказаною конфігурацією. наприклад,
Info: Запити виконані через yii \ db \ Command :: execute () визначаються як запити на запис, а всі інші запити через один з "query" методів yii \ db \ Command сприймаються як запити на читання. Ви можете отримати поточний статус з'єднання до підлеглого сервера через $ db-> slave.
Компонент Connection підтримує балансування навантаження і перемикання при збої для підлеглих серверів. При виконанні першого запиту на читання, компонент Connection буде випадковим чином вибирати підлеглий сервер і спробує підключитися до нього. Якщо сервер виявиться "мертвим", він спробує підключитися до іншого. Якщо жоден з підлеглих сервер не буде доступний, він підключиться до майстра. Якщо налаштувати кеш статусу серверів. то недоступність серверів може бути запам'ятав, щоб не використовуватися протягом заданого проміжку часу.
Info: У конфігурації вище, таймаут з'єднання до підлеглого сервера налаштований на 10 секунд. Це означає, що якщо сервер не відповість за 10 секунд, він буде вважатися "мертвим". Ви можете відрегулювати цей параметр виходячи з налаштувань вашої середовища.
Ви також можете налаштувати декілька основних і кілька підлеглих серверів. наприклад,
Конфігурація вище, визначає два основних і чотири підлеглих серверів. Компонент Connection підтримує балансування навантаження і перемикання при збої між основними серверами, також як і між підлеглими. Різниця полягає в тому, що коли до жодного з основних серверів не вдасться підключитися буде викинуто виключення.
Note: Коли ви використовуєте властивість masters для настройки одного або декількох основних серверів, всі інші властивості для налаштування з'єднання з базою даних (такі як dsn. Username. Password) будуть проігноровані компонентом Connection.
За замовчуванням, транзакції використовують з'єднання з основним сервером. І в рамках транзакції, всі операції з БД будуть використовувати з'єднання з основним сервером. наприклад,
Якщо ви хочете запустити транзакцію на підлеглому сервері, ви повинні вказати це явно, як показано нижче:
Іноді може знадобитися виконати запит на читання через підключення до основного сервера. Це може бути досягнуто з використанням методу useMaster ():
Ви також можете явно встановити $ db-> enableSlaves в брехню, щоб направляти всі запити до з'єднання з майстром.
Робота зі схемою бази даних
Yii DAO надає цілий набір методів для управління схемою бази даних, таких як створення нових таблиць, видалення стовпців з таблиці, і т.д. Ці методи описані нижче:
Ці методи можуть бути використані, як зазначено нижче:
Ви також зможете отримати опис схеми таблиці через виклик методу getTableSchema (). наприклад,
Метод поверне об'єкт yii \ db \ TableSchema. який містить інформацію про шпальтах таблиці, первинних ключах, зовнішні ключі, і т.д. Вся ця інформація використовується головним чином для будівника запитів і active record. щоб допомогти вам писати незалежний від бази даних код.