База даних Nette
Nette Database – це потужний та елегантний рівень баз даних для PHP, який фокусується на простоті та розумних функціях. Вона пропонує два взаємодоповнюючих способи роботи з даними – за допомогою провідника для швидкої розробки або за допомогою SQL для повного контролю над запитами.
SQL спосіб
- Безпечні параметризовані запити
- Точний контроль над структурою SQL-запитів
- Ідеально підходить для написання складних запитів з розширеними функціями
- Оптимізація продуктивності за допомогою спеціальних функцій SQL
Шлях дослідника
- Швидка розробка без написання SQL
- Інтуїтивно зрозуміла робота зі зв'язками між таблицями
- Автоматична оптимізація запитів
- Чудово підходить для швидкої та зручної взаємодії з базами даних
Встановлення
Ви можете завантажити та встановити бібліотеку за допомогою Composer:
composer require nette/database
Підтримувані бази даних
Nette Database підтримує наступні бази даних:
Сервер бази даних | Ім'я DSN | Підтримка провідника |
---|---|---|
MySQL (>= 5.1) | mysql | ТАК |
PostgreSQL (>= 9.0) | pgsql | ТАК |
SQLite 3 (>= 3.8) | sqlite | ТАК |
Oracle | oci | НІ |
MS SQL (PDO_SQLSRV) | sqlsrv | YES | | MS SQL (PDO_SQLSRV) MS SQL (PDO_DBLIB) | mssql | NO | | ODBC | oci | NO ODBC | odbc | NO | | ODBC | NO | | ODBC | ODBC | NO | | ODBC | ODBC | NO
Два підходи до роботи з базами даних
У Nette Database ви можете писати SQL-запити безпосередньо (спосіб SQL) або дозволити SQL генеруватися автоматично (спосіб Explorer). Давайте подивимося, як обидва підходи вирішують одні й ті ж завдання:
SQL-шлях – написання SQL-запитів
// Вставити запис
$database->query('INSERT INTO books', [
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Отримати записи: автори книг
$result = $database->query('
SELECT authors.*, COUNT(books.id) AS books_count
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE authors.active = 1
GROUP BY authors.id
');
// Відображення (не оптимально, генерує N додаткових запитів)
foreach ($result as $author) {
$books = $database->query('
SELECT * FROM books
WHERE author_id = ?
ORDER BY published_at DESC
', $author->id);
echo "Author $author->name has written $author->books_count books:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
Провідник – Автоматична генерація SQL
// Вставити запис
$database->table('books')->insert([
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Отримати записи: автори книг
$authors = $database->table('authors')
->where('active', 1);
// Відображення (автоматично генерує лише 2 оптимізовані запити)
foreach ($authors as $author) {
$books = $author->related('books')
->order('published_at DESC');
echo "Author $author->name has written {$books->count()} books:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
Провідник генерує та оптимізує SQL-запити автоматично. У наведеному вище прикладі спосіб SQL генерує N+1 запит (один для авторів і один для книг кожного автора), тоді як Провідник виконує лише два оптимізовані запити – один для авторів, а інший для всіх їхніх книг.
Ви можете вільно комбінувати обидва підходи у своїй програмі за потреби.
Підключення та налаштування
Для підключення до бази даних просто створіть екземпляр класу Nette\Database\Connection:
$database = new Nette\Database\Connection($dsn, $user, $password);
Параметр $dsn
(ім'я джерела даних) має той самий формат, що і PDO, наприклад,
host=127.0.0.1;dbname=test
. Якщо з'єднання не вдається, то повертається
параметр Nette\Database\ConnectionException
.
Однак, більш зручним методом є використання конфігурації програми. Додайте розділ
database
, і будуть створені необхідні об'єкти, в тому числі панель
бази даних в Tracy Debug Bar.
database:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: password
Після цього об'єкт з'єднання може бути отриманий як сервіс з контейнера DI, наприклад
class Model
{
public function __construct(
// or Nette\Database\Explorer
private Nette\Database\Connection $database,
) {
}
}
Для отримання додаткової інформації див. розділ Конфігурація бази даних.
Створення Провідника вручну
Якщо ви не використовуєте контейнер Nette DI, ви можете вручну створити
екземпляр Nette\Database\Explorer
:
// database connection
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// cache storage, implements Nette\Caching\Storage, e.g.:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// handles database structure reflection
$structure = new Nette\Database\Structure($connection, $storage);
// defines rules for mapping table names, columns, and foreign keys
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);
Управління з'єднаннями
Коли ви створюєте об'єкт Connection
, він підключається до бази
даних автоматично. Якщо ви хочете затримати з'єднання, увімкніть
лінивий режим у конфігурації,
встановивши lazy
, або зробіть це так:
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
Для керування з'єднанням використовуйте методи connect()
,
disconnect()
та reconnect()
.
connect()
встановлює з'єднання, якщо воно ще не було встановлено, і може повернутиNette\Database\ConnectionException
.disconnect()
від'єднує від бази даних.reconnect()
від'єднує, а потім знову підключається до бази даних, а також може повернутиNette\Database\ConnectionException
.
Крім того, ви можете відстежувати події з'єднання за допомогою події
onConnect
, яка являє собою масив зворотних викликів, що виконуються
після з'єднання з базою даних.
// Викликається після підключення до бази даних
$database->onConnect[] = function($database) {
echo "Connected to the database";
};
Tracy Debug Bar
Якщо ви використовуєте Tracy, панель Database в Debug Bar буде автоматично ввімкнена. Вона відображає всі виконані запити, їх параметри, час виконання і місце в коді, де вони були викликані.