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 AusnahmeNette\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 AusnahmeNette\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.
