Nette Database

Nette Database ist eine leistungsstarke und elegante Datenbankschicht für PHP mit Schwerpunkt auf Einfachheit und intelligenten Funktionen. Sie bietet zwei Möglichkeiten zur Arbeit mit der Datenbank: den Explorer für eine schnelle Anwendungsentwicklung oder den SQL-Zugriff für die direkte Arbeit mit Abfragen.

SQL-Zugriff

  • Sichere parametrisierte Abfragen
  • Präzise Kontrolle über die Form der SQL-Abfragen
  • Ideal für komplexe Abfragen mit erweiterten Funktionen
  • Optimierung der Leistung mithilfe spezifischer SQL-Funktionen

Explorer

  • Schnelle Entwicklung ohne manuelles Schreiben von SQL
  • Intuitive Arbeit mit Beziehungen zwischen Tabellen
  • Automatische Optimierung von Abfragen
  • Geeignet für schnelle und bequeme Arbeit mit der Datenbank

Installation

Die Bibliothek wird mit dem Werkzeug Composer heruntergeladen und installiert:

composer require nette/database

Unterstützte Datenbanken

Nette Database unterstützt die folgenden Datenbanken:

Datenbankserver DSN-Name Unterstützung in Explorer
MySQL (>= 5.1) mysql Ja
PostgreSQL (>= 9.0) pgsql Ja
SQLite 3 (>= 3.8) sqlite Ja
Oracle oci Nein
MS SQL (PDO_SQLSRV) sqlsrv Ja
MS SQL (PDO_DBLIB) mssql Nein
ODBC odbc Nein

Zwei Zugänge zur Datenbank

Nette Database gibt Ihnen die Wahl: Sie können entweder SQL-Abfragen direkt schreiben (SQL-Zugriff) oder sie automatisch generieren lassen (Explorer). Sehen wir uns an, wie beide Ansätze dieselben Aufgaben lösen:

SQL-Zugriff – Manuelle SQL-Abfragen

// Einfügen eines Datensatzes
$database->query('INSERT INTO books', [
	'author_id' => $authorId,
	'title' => $bookData->title,
	'published_at' => new DateTime,
]);

// Abrufen von Datensätzen: Aktive Autoren und ihre Buchanzahl
$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
');

// Ausgabe (nicht optimal, generiert N weitere Abfragen - N+1 Problem)
foreach ($result as $author) {
	$books = $database->query('
		SELECT * FROM books
		WHERE author_id = ?
		ORDER BY published_at DESC
	', $author->id);

	echo "Autor $author->name hat $author->books_count Bücher geschrieben:\n";

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

Explorer-Zugriff – Automatische Generierung von SQL

// Einfügen eines Datensatzes
$database->table('books')->insert([
	'author_id' => $authorId,
	'title' => $bookData->title,
	'published_at' => new DateTime,
]);

// Abrufen von Datensätzen: Aktive Autoren
$authors = $database->table('authors')
	->where('active', true);

// Ausgabe (automatisch optimiert, generiert nur 2 Abfragen)
foreach ($authors as $author) {
	$books = $author->related('books') // Holt zugehörige Bücher
		->order('published_at DESC');

	echo "Autor $author->name hat {$books->count()} Bücher geschrieben:\n";

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

Der Explorer-Zugriff generiert und optimiert SQL-Abfragen automatisch. Im gezeigten Beispiel generiert der SQL-Zugriff N+1 Abfragen (eine für Autoren und dann eine für die Bücher jedes Autors), während der Explorer die Abfragen automatisch optimiert und nur zwei durchführt – eine für Autoren und eine für alle ihre Bücher auf einmal.

Beide Ansätze können in der Anwendung nach Bedarf beliebig kombiniert werden.

Verbindung und Konfiguration

Um eine Verbindung zur Datenbank herzustellen, genügt es, eine Instanz der Klasse Nette\Database\Connection zu erstellen:

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

Der Parameter $dsn (Data Source Name) ist derselbe, den PDO verwendet, z.B. mysql:host=127.0.0.1;dbname=test. Im Fehlerfall wird eine Ausnahme Nette\Database\ConnectionException ausgelöst.

Ein eleganterer Weg ist jedoch die Verwendung der Anwendungskonfiguration. Fügen Sie einfach einen database-Abschnitt hinzu, und die erforderlichen Objekte (Connection und Explorer) werden erstellt. Außerdem wird ein Datenbankpanel in der Tracy Debug-Leiste angezeigt.

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

Danach erhalten Sie das Verbindungsobjekt oder den Explorer als Dienst aus dem DI-Container, z.B. über Constructor Injection:

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

Mehr Informationen zur Datenbankkonfiguration.

Manuelle Erstellung des Explorers

Wenn Sie keinen Nette DI-Container verwenden, können Sie die Instanz Nette\Database\Explorer manuell erstellen:

// Verbindung zur Datenbank
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// Speicher für Cache, implementiert Nette\Caching\Storage, z.B.:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// kümmert sich um die Reflexion der Datenbankstruktur
$structure = new Nette\Database\Structure($connection, $storage);
// definiert Regeln für das Mapping von Tabellen-, Spalten- und Fremdschlüsselnamen
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);

Verbindungsverwaltung

Beim Erstellen des Connection-Objekts wird die Verbindung automatisch hergestellt. Wenn Sie die Verbindung verzögern möchten, verwenden Sie den Lazy-Modus – diesen aktivieren Sie in der Konfiguration durch Setzen von lazy, oder so:

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

Zur Verwaltung der Verbindung nutzen Sie die Methoden connect(), disconnect() und reconnect().

  • connect() stellt die Verbindung her, falls sie noch nicht existiert, und kann eine Ausnahme Nette\Database\ConnectionException auslösen.
  • disconnect() trennt die aktuelle Verbindung zur Datenbank.
  • reconnect() führt eine Trennung und anschließende erneute Verbindung zur Datenbank durch. Diese Methode kann ebenfalls eine Ausnahme Nette\Database\ConnectionException auslösen.

Darüber hinaus können Sie Ereignisse im Zusammenhang mit der Verbindung über das Ereignis onConnect verfolgen, ein Array von Callbacks, die nach dem Aufbau der Verbindung zur Datenbank aufgerufen werden.

// wird nach der Verbindung zur Datenbank ausgeführt
$database->onConnect[] = function($database) {
	echo "Verbunden mit der Datenbank";
};

Tracy Debug Bar

Wenn Sie Tracy verwenden, wird automatisch das Database-Panel in der Debug-Bar aktiviert, das alle ausgeführten Abfragen, ihre Parameter, die Ausführungszeit und den Ort im Code anzeigt, an dem sie aufgerufen wurden.

Version: 4.0