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 |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 да се генерира автоматично (подход на изследователя). Нека видим как двата подхода решават едни и същи задачи:

[Директен подход |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";
};
```


Лентата за отстраняване на грешки на Tracy .[#toc-tracy-debug-bar]
==================================================================

Ако използвате [Tracy |tracy:], панелът Database (База данни) в лентата за отстраняване на грешки се активира автоматично. В него се показват всички изпълнени заявки, техните параметри, времето на изпълнение и мястото в кода, където са били извикани.

[* db-panel.webp *]


Поддържани бази данни .[#toc-supported-databases]
=================================================

Nette Database поддържа следните бази данни:

| **Сървър на базата данни** | **ДНС име** | **Поддръжка на изследователя** |
|-----------------------|--------------|-----------------------|
| MySQL (>= 5.1) | mysql | YES |
| PostgreSQL (>= 9.0) | pgsql | ДА |
| SQLite 3 (>= 3.8) | sqlite | ДА |
| Oracle | oci | НЕ |
| MS SQL (PDO_SQLSRV) | sqlsrv | ДА |
| MS SQL (PDO_DBLIB) | mssql | НЕ |
| ODBC | odbc | НЕ |

База данни Nette

Nette Database е мощен и елегантен слой за бази данни за PHP, известен със своята простота и интелигентни функции. Той не изисква сложна конфигурация или генериране на същности, което ви позволява да започнете работа с него веднага.

С Nette Database можете да работите по два начина:

Директен SQL

  • Безопасни параметризирани заявки
  • Прецизен контрол върху структурата на SQL заявките
  • Идеални за писане на сложни заявки с разширени функции
  • Оптимизиране на производителността с помощта на специфични SQL функции

Explorer

  • Бърза разработка без писане на 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 да се генерира автоматично (подход на изследователя). Нека видим как двата подхода решават едни и същи задачи:

Директен подход – писане на 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

Ако използвате Tracy, панелът Database (База данни) в лентата за отстраняване на грешки се активира автоматично. В него се показват всички изпълнени заявки, техните параметри, времето на изпълнение и мястото в кода, където са били извикани.

Поддържани бази данни

Nette Database поддържа следните бази данни:

Сървър на базата данни ДНС име Поддръжка на изследователя
MySQL (>= 5.1) mysql YES
PostgreSQL (>= 9.0) pgsql ДА
SQLite 3 (>= 3.8) sqlite ДА
Oracle oci НЕ
MS SQL (PDO_SQLSRV) sqlsrv ДА
MS SQL (PDO_DBLIB) mssql НЕ
ODBC odbc НЕ