Nette Database

Nette Database — це потужний та елегантний шар бази даних для PHP з акцентом на простоту та розумні функції. Він пропонує два способи роботи з базою даних — Explorer для швидкої розробки додатків або SQL підхід для прямої роботи з запитами.

SQL підхід

  • Безпечні параметризовані запити
  • Точний контроль над формою SQL-запитів
  • Коли ви пишете складні запити з розширеними функціями
  • Оптимізуєте продуктивність за допомогою специфічних функцій SQL

Explorer

  • Розробляєте швидко, не пишучи SQL
  • Інтуїтивна робота з відношеннями між таблицями
  • Оціните автоматичну оптимізацію запитів
  • Підходить для швидкої та зручної роботи з базою даних

Встановлення

Завантажте та встановіть бібліотеку за допомогою інструмента Composer:

composer require nette/database

Підтримувані бази даних

Nette Database підтримує наступні бази даних:

Сервер бази даних Ім'я DSN Підтримка в Explorer
MySQL (>= 5.1) mysql ТАК
PostgreSQL (>= 9.0) pgsql ТАК
Sqlite 3 (>= 3.8) sqlite ТАК
Oracle oci
MS SQL (PDO_SQLSRV) sqlsrv ТАК
MS SQL (PDO_DBLIB) mssql
ODBC odbc

Два підходи до бази даних

Nette Database надає вам вибір: ви можете або писати 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->name написав $author->books_count книг:\n";

	foreach ($books as $book) {
		echo "- $book->title\n";
	}
}

Explorer підхід – автоматичне генерування 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->name написав {$books->count()} книг:\n";

	foreach ($books as $book) {
		echo "- $book->title\n";
	}
}

Підхід Explorer генерує та оптимізує SQL-запити автоматично. У наведеному прикладі SQL підхід генерує N+1 запитів (один для авторів, а потім один для книг кожного автора), тоді як Explorer автоматично оптимізує запити та виконує лише два – один для авторів та один для всіх їхніх книг.

Обидва підходи можна вільно комбінувати в додатку за потреби.

Підключення та конфігурація

Для підключення до бази даних достатньо створити екземпляр класу Nette\Database\Connection:

$database = new Nette\Database\Connection($dsn, $user, $password);

Параметр $dsn (data source name) такий самий, який використовує PDO, наприклад mysql:host=127.0.0.1;dbname=test. У разі збою викидається виняток Nette\Database\ConnectionException.

Однак, зручніший спосіб пропонує конфігурація програми, куди достатньо додати секцію database, і будуть створені необхідні об'єкти, а також панель бази даних у Tracy барі.

database:
	dsn: 'mysql:host=127.0.0.1;dbname=test'
	user: root
	password: password

Потім об'єкт з'єднання отримаємо як сервіс з DI-контейнера, наприклад:

class Model
{
	public function __construct(
		// або Nette\Database\Explorer
		private Nette\Database\Connection $database,
	) {
	}
}

Більше інформації про конфігурацію бази даних.

Ручне створення Explorer

Якщо ви не використовуєте Nette DI-контейнер, ви можете створити екземпляр Nette\Database\Explorer вручну:

// підключення до бази даних
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// сховище для кешу, реалізує Nette\Caching\Storage, наприклад:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// відповідає за рефлексію структури бази даних
$structure = new Nette\Database\Structure($connection, $storage);
// визначає правила для відображення назв таблиць, стовпців та зовнішніх ключів
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);

Управління підключенням

При створенні об'єкта Connection підключення відбувається автоматично. Якщо ви хочете відкласти підключення, використовуйте режим lazy – його можна увімкнути в конфігурації, встановивши lazy: true, або так:

$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 "Підключено до бази даних";
};

Tracy Debug Bar

Якщо ви використовуєте Tracy, автоматично активується панель Database в Debug барі, яка відображає всі виконані запити, їхні параметри, час виконання та місце в коді, де вони були викликані.

версія: 4.0