Nette Documentation Preview

syntax
База данных Nette
*****************

.[perex]
Nette Database - это мощный и элегантный слой баз данных для PHP, известный своей простотой и продуманными функциями. Он не требует сложной настройки или генерации сущностей, что позволяет вам сразу же начать работать с ним.

С Nette Database вы можете работать в двух направлениях:

<div class="grid gap-3">
<div>


[Прямой SQL |Direct SQL]
========================
- Безопасные, параметризованные запросы
- Точный контроль над структурой SQL-запросов
- Идеально подходит для написания сложных запросов с расширенными функциями
- Оптимизация производительности с помощью специальных функций SQL

</div>

<div>


[Исследователь |Explorer]
=========================
- Быстрая разработка без написания SQL
- Интуитивно понятная обработка отношений между таблицами
- Автоматическая оптимизация запросов
- Отлично подходит для быстрого и удобного взаимодействия с базой данных

</div>

</div>


Установка .[#toc-installation]
==============================

Вы можете загрузить и установить библиотеку с помощью [Composer |best-practices:composer]:

```shell
composer require nette/database
```


Подключение и конфигурация .[#toc-connection-and-configuration]
===============================================================

Чтобы подключиться к базе данных, просто создайте экземпляр класса [api:Nette\Database\Connection]:

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

Параметр `$dsn` (имя источника данных) имеет тот же формат, что и [в PDO |https://www.php.net/manual/en/pdo.construct.php#refsect1-pdo.construct-parameters], например, `host=127.0.0.1;dbname=test`. Если соединение не удается, выбрасывается ошибка `Nette\Database\ConnectionException`.

Однако более удобным методом является использование [конфигурации приложения |configuration]. Добавьте секцию `database`, и необходимые объекты будут созданы, включая панель базы данных в отладочной панели [Tracy |tracy:].

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

После этого объект соединения можно [получить как сервис из контейнера DI |dependency-injection:passing-dependencies], например:

```php
class Model
{
	public function __construct(
		private Nette\Database\Connection $database,
	) {
	}
}
```

Дополнительные сведения см. в разделе [Конфигурация базы данных |configuration].


Два подхода к работе с базами данных .[#toc-two-approaches-to-database-work]
============================================================================

В Nette Database вы можете либо писать SQL-запросы напрямую (прямой подход), либо позволить SQL генерироваться автоматически (подход Explorer). Давайте посмотрим, как оба подхода решают одни и те же задачи:

[Прямой подход |direct-sql] - написание SQL-запросов

```php
// Вставить запись
$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";
	}
}
```

[Исследовательский подход |explorer] - автоматическая генерация SQL-запросов

```php
// Вставить запись
$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";
	}
}
```

Подход Explorer генерирует и оптимизирует SQL-запросы автоматически. В приведенном выше примере прямой подход генерирует N+1 запрос (один для авторов и один для книг каждого автора), в то время как Explorer выполняет только два оптимизированных запроса - один для авторов и другой для всех их книг.

Вы можете свободно комбинировать оба подхода в своем приложении по мере необходимости.


Управление соединениями .[#toc-connection-management]
=====================================================

Когда вы создаете объект `Connection`, он подключается к базе данных автоматически. Если вы хотите отложить подключение, включите ленивый режим в [конфигурации |configuration], установив `lazy`, или сделайте это следующим образом:

```php
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
```

Для управления подключением используйте методы `connect()`, `disconnect()` и `reconnect()`.
- `connect()` устанавливает соединение, если оно еще не было установлено, и может выбросить ошибку `Nette\Database\ConnectionException`.
- `disconnect()` отсоединяется от базы данных.
- `reconnect()` отключается, а затем снова подключается к базе данных и может также выдать ошибку `Nette\Database\ConnectionException`.

Кроме того, вы можете отслеживать события подключения с помощью события `onConnect`, которое представляет собой массив обратных вызовов, выполняемых после подключения к базе данных.

```php
// Вызывается после подключения к базе данных
$database->onConnect[] = function($database) {
	echo "Connected to the database";
};
```


Панель отладки Трейси .[#toc-tracy-debug-bar]
=============================================

Если вы используете [Tracy |tracy:], панель Database в Debug Bar включается автоматически. На ней отображаются все выполненные запросы, их параметры, время выполнения и место в коде, где они были вызваны.

[* db-panel.webp *]


Поддерживаемые базы данных .[#toc-supported-databases]
======================================================

Nette Database поддерживает следующие базы данных:

| **Сервер баз данных** | **Имя DSN** | **Поддержка эксплорера** | **Поддержка эксплорера**.
|-----------------------|--------------|-----------------------|
| MySQL (>= 5.1) | mysql | YES |
| PostgreSQL (>= 9.0) | pgsql | YES |
| SQLite 3 (>= 3.8) | sqlite | YES |
| Oracle | oci | NO |
| MS SQL (PDO_SQLSRV) | sqlsrv | YES |
| MS SQL (PDO_DBLIB) | mssql | NO |
| ODBC | odbc | NO |

База данных Nette

Nette Database – это мощный и элегантный слой баз данных для PHP, известный своей простотой и продуманными функциями. Он не требует сложной настройки или генерации сущностей, что позволяет вам сразу же начать работать с ним.

С Nette Database вы можете работать в двух направлениях:

Прямой SQL

  • Безопасные, параметризованные запросы
  • Точный контроль над структурой SQL-запросов
  • Идеально подходит для написания сложных запросов с расширенными функциями
  • Оптимизация производительности с помощью специальных функций SQL

Исследователь

  • Быстрая разработка без написания SQL
  • Интуитивно понятная обработка отношений между таблицами
  • Автоматическая оптимизация запросов
  • Отлично подходит для быстрого и удобного взаимодействия с базой данных

Установка

Вы можете загрузить и установить библиотеку с помощью Composer:

composer require nette/database

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

Чтобы подключиться к базе данных, просто создайте экземпляр класса 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.

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

После этого объект соединения можно получить как сервис из контейнера DI, например:

class Model
{
	public function __construct(
		private Nette\Database\Connection $database,
	) {
	}
}

Дополнительные сведения см. в разделе Конфигурация базы данных.

Два подхода к работе с базами данных

В Nette Database вы можете либо писать SQL-запросы напрямую (прямой подход), либо позволить SQL генерироваться автоматически (подход Explorer). Давайте посмотрим, как оба подхода решают одни и те же задачи:

Прямой подход – написание 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";
	}
}

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

Вы можете свободно комбинировать оба подхода в своем приложении по мере необходимости.

Управление соединениями

Когда вы создаете объект 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, панель Database в Debug Bar включается автоматически. На ней отображаются все выполненные запросы, их параметры, время выполнения и место в коде, где они были вызваны.

Поддерживаемые базы данных

Nette Database поддерживает следующие базы данных:

Сервер баз данных Имя DSN Поддержка эксплорера Поддержка эксплорера.
MySQL (>= 5.1) mysql YES  
PostgreSQL (>= 9.0) pgsql YES  
SQLite 3 (>= 3.8) sqlite YES  
Oracle oci NO  
MS SQL (PDO_SQLSRV) sqlsrv YES  
MS SQL (PDO_DBLIB) mssql NO  
ODBC odbc NO