Nette Database

Nette Database est une couche de base de données puissante et élégante pour PHP, axée sur la simplicité et les fonctionnalités intelligentes. Elle propose deux façons de travailler avec votre base : l'Explorer pour développer rapidement, ou l'approche SQL pour manipuler directement les requêtes.

Approche SQL

  • Requêtes paramétrées et sûres
  • Contrôle précis de la structure des requêtes SQL
  • Quand vous écrivez des requêtes complexes avec des fonctions avancées
  • Optimisation des performances à l'aide de fonctions SQL spécifiques

Explorer

  • Développer vite sans écrire de SQL
  • Manipulation intuitive des relations entre les tables
  • Profiter de l'optimisation automatique des requêtes
  • Convient à un travail rapide et confortable avec la base

Installation

Téléchargez et installez la bibliothèque à l'aide de Composer :

composer require nette/database

Bases de données prises en charge

Nette Database prend en charge les bases de données suivantes :

Serveur de base de données Nom DSN Prise en charge Explorer
MySQL (>= 5.1) mysql OUI
PostgreSQL (>= 9.0) pgsql OUI
SQLite 3 (>= 3.8) sqlite OUI
Oracle oci NON
MS SQL (PDO_SQLSRV) sqlsrv OUI
MS SQL (PDO_DBLIB) mssql NON
ODBC odbc NON

Deux approches du travail avec la base de données

Nette Database vous laisse le choix : vous pouvez soit écrire directement les requêtes SQL (approche SQL), soit les laisser être générées automatiquement (Explorer). Voyons comment les deux approches traitent les mêmes tâches :

Approche SQL – requêtes SQL

// Insère un enregistrement
$database->query('INSERT INTO books', [
	'author_id' => $authorId,
	'title' => $bookData->title,
	'published_at' => new DateTime,
]);

// Récupère des enregistrements : les auteurs des livres
$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
');

// Affichage (pas optimal, génère N requêtes supplémentaires)
foreach ($result as $author) {
	$books = $database->query('
		SELECT * FROM books
		WHERE author_id = ?
		ORDER BY published_at DESC
	', $author->id);

	echo "L'auteur $author->name a écrit $author->books_count livres :\n";

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

Approche Explorer – génération automatique du SQL

// Insère un enregistrement
$database->table('books')->insert([
	'author_id' => $authorId,
	'title' => $bookData->title,
	'published_at' => new DateTime,
]);

// Récupère des enregistrements : les auteurs des livres
$authors = $database->table('authors')
	->where('active', 1);

// Affichage (génère automatiquement seulement 2 requêtes optimisées)
foreach ($authors as $author) {
	$books = $author->related('books')
		->order('published_at DESC');

	echo "L'auteur $author->name a écrit {$books->count()} livres :\n";

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

L'approche Explorer génère et optimise les requêtes SQL automatiquement. Dans l'exemple ci-dessus, l'approche SQL génère N+1 requêtes (une pour les auteurs, puis une pour les livres de chaque auteur), tandis qu'Explorer optimise automatiquement les requêtes et n'en exécute que deux : une pour les auteurs et une pour tous leurs livres.

Les deux approches peuvent être librement combinées dans votre application, selon les besoins.

Connexion et configuration

Pour vous connecter à la base de données, il suffit de créer une instance de la classe Nette\Database\Connection :

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

Le paramètre $dsn (Data Source Name) est le même que celui utilisé par PDO, par exemple host=127.0.0.1;dbname=test. En cas d'échec, il lève une Nette\Database\ConnectionException.

Une méthode plus commode est cependant offerte par la configuration de l'application, où il vous suffit d'ajouter une section database. Cela crée les objets nécessaires ainsi qu'un panneau de base de données dans la barre de Tracy.

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

L'objet de connexion peut ensuite être obtenu comme service depuis le conteneur DI, par exemple :

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

Plus d'informations sur la configuration de la base de données.

Création manuelle de l'Explorer

Si vous n'utilisez pas le conteneur DI de Nette, vous pouvez créer manuellement une instance de Nette\Database\Explorer :

// connexion à la base de données
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// stockage du cache, implémente Nette\Caching\Storage, par exemple :
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// se charge de la réflexion de la structure de la base
$structure = new Nette\Database\Structure($connection, $storage);
// définit les règles de mapping des noms de tables, de colonnes et de clés étrangères
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);

Gestion de la connexion

Lors de la création d'un objet Connection, la connexion est établie automatiquement. Si vous voulez la différer, utilisez le mode lazy : activez-le dans la configuration en définissant lazy, ou ainsi :

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

Pour gérer la connexion, utilisez les méthodes connect(), disconnect() et reconnect().

  • connect() crée une connexion si elle n'existe pas déjà et peut lever une Nette\Database\ConnectionException.
  • disconnect() ferme la connexion courante à la base de données.
  • reconnect() effectue une déconnexion suivie d'une reconnexion à la base. Cette méthode peut elle aussi lever une Nette\Database\ConnectionException.

Vous pouvez en outre surveiller les événements liés à la connexion à l'aide de l'événement onConnect, qui est un tableau de callbacks appelés après l'établissement de la connexion à la base.

// s'exécute après la connexion à la base de données
$database->onConnect[] = function($database) {
	echo "Connecté à la base de données";
};

L'événement onQuery fonctionne de la même façon : c'est un tableau de callbacks invoqués après chaque requête exécutée (et lorsqu'une requête échoue), utile pour la journalisation ou le profilage.

Barre de débogage Tracy

Si vous utilisez Tracy, le panneau Database de la Debug Bar est activé automatiquement. Il affiche toutes les requêtes exécutées, leurs paramètres, leur temps d'exécution et l'endroit du code d'où elles ont été appelées.