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+1 запросов)
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, например, 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
Если вы не используете DI-контейнер Nette, вы можете создать экземпляр
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: 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 Bar активируется автоматически. Она отображает все выполненные запросы, их параметры, время выполнения и место в коде, где они были вызваны.
