Database Nette
Nette Database è un livello di database potente ed elegante per PHP, con un'attenzione particolare alla semplicità e alle funzioni intelligenti. Offre due modi complementari di lavorare con i dati: utilizzando l'Explorer per lo sviluppo rapido o il metodo SQL per il pieno controllo delle query.
Modo SQL
- Query sicure e parametrizzate
- Controllo preciso sulla struttura delle query SQL
- Ideale per scrivere query complesse con funzioni avanzate
- Ottimizzazione delle prestazioni grazie a funzioni SQL specifiche
La via dell'esploratore
- Sviluppo veloce senza scrivere SQL
- Gestione intuitiva delle relazioni tra tabelle
- Ottimizzazione automatica delle query
- Ottimo per interazioni rapide e convenienti con il database
Installazione
È possibile scaricare e installare la libreria utilizzando Composer:
composer require nette/database
Database supportati
Nette Database supporta i seguenti database:
Server di database | Nome DSN | Supporto Explorer |
---|---|---|
MySQL (>= 5.1) | mysql | SI' |
PostgreSQL (>= 9.0) | pgsql | SÌ |
SQLite 3 (>= 3.8) | sqlite | SÌ |
Oracle | oci | NO |
MS SQL (PDO_SQLSRV) | sqlsrv | SI' |
MS SQL (PDO_DBLIB) | mssql | NO |
ODBC | odbc | NO |
Due approcci al lavoro sui database
Con Nette Database, è possibile scrivere direttamente le query SQL (metodo SQL) o lasciare che l'SQL venga generato automaticamente (metodo Explorer). Vediamo come entrambi gli approcci risolvono gli stessi compiti:
Modo SQL – Scrittura di query SQL
// Inserire un record
$database->query('INSERT INTO books', [
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Recuperare i record: autori di libri
$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
');
// Visualizzazione (non ottimale, genera N query aggiuntive)
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";
}
}
Modo Explorer – Generazione automatica di SQL
// Inserire un record
$database->table('books')->insert([
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// Recuperare record: autori di libri
$authors = $database->table('authors')
->where('active', 1);
// Visualizzazione (genera automaticamente solo 2 query ottimizzate)
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";
}
}
L'approccio Explorer genera e ottimizza automaticamente le query SQL. Nell'esempio precedente, il metodo SQL genera N+1 query (una per gli autori e una per i libri di ciascun autore), mentre Explorer esegue solo due query ottimizzate, una per gli autori e una per tutti i loro libri.
È possibile combinare liberamente entrambi gli approcci nella propria applicazione, a seconda delle necessità.
Connessione e configurazione
Per connettersi al database, è sufficiente creare un'istanza della classe Nette\Database\Connection:
$database = new Nette\Database\Connection($dsn, $user, $password);
Il parametro $dsn
(nome dell'origine dati) segue lo stesso formato utilizzato da PDO, ad esempio
host=127.0.0.1;dbname=test
. Se la connessione fallisce, viene lanciata l'istanza
Nette\Database\ConnectionException
.
Tuttavia, un metodo più comodo è quello di utilizzare la configurazione dell'applicazione. Aggiungendo una sezione
database
, verranno creati gli oggetti necessari, compreso un pannello del database nella barra di debug di Tracy.
database:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: password
Dopodiché, l'oggetto connessione può essere recuperato come servizio dal contenitore DI, ad esempio:
class Model
{
public function __construct(
// or Nette\Database\Explorer
private Nette\Database\Connection $database,
) {
}
}
Per ulteriori informazioni, vedere Configurazione del database.
Creazione manuale di Explorer
Se non si utilizza il contenitore Nette DI, è possibile creare manualmente un'istanza di
Nette\Database\Explorer
:
// database connection
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// cache storage, implements Nette\Caching\Storage, e.g.:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// handles database structure reflection
$structure = new Nette\Database\Structure($connection, $storage);
// defines rules for mapping table names, columns, and foreign keys
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);
Gestione delle connessioni
Quando si crea un oggetto Connection
, questo si connette automaticamente al database. Se si vuole ritardare la
connessione, attivare la modalità pigra nella configurazione,
impostando lazy
, oppure procedere in questo modo:
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
Per gestire la connessione, utilizzare i metodi connect()
, disconnect()
, e
reconnect()
.
connect()
stabilisce una connessione se non è già stata stabilita e può lanciare unNette\Database\ConnectionException
.disconnect()
si disconnette dal database.reconnect()
si disconnette e poi si riconnette al database e può anche lanciare unNette\Database\ConnectionException
.
Inoltre, è possibile monitorare gli eventi di connessione utilizzando l'evento onConnect
, che è un array di
callback eseguiti dopo la connessione al database.
// Richiamato dopo la connessione al database
$database->onConnect[] = function($database) {
echo "Connected to the database";
};
Barra di Debug Tracy
Se si utilizza Tracy, il pannello Database della barra di debug viene automaticamente attivato. Esso visualizza tutte le query eseguite, i loro parametri, il tempo di esecuzione e la posizione nel codice in cui sono state chiamate.