Baza danych Nette

Nette Database to potężna i elegancka warstwa bazy danych dla PHP, znana ze swojej prostoty i inteligentnych funkcji. Nie wymaga skomplikowanej konfiguracji ani generowania encji, co pozwala na natychmiastowe rozpoczęcie pracy.

Z Nette Database można pracować na dwa sposoby:

Bezpośredni SQL

  • Bezpieczne, parametryzowane zapytania
  • Precyzyjna kontrola nad strukturą zapytań SQL
  • Idealny do pisania złożonych zapytań z zaawansowanymi funkcjami
  • Optymalizacja wydajności przy użyciu określonych funkcji SQL

Explorer

  • Szybki rozwój bez pisania SQL
  • Intuicyjna obsługa relacji między tabelami
  • Automatyczna optymalizacja zapytań
  • Doskonały do szybkich i wygodnych interakcji z bazą danych

Instalacja

Bibliotekę można pobrać i zainstalować za pomocą Composera:

composer require nette/database

Połączenie i konfiguracja

Aby połączyć się z bazą danych, wystarczy utworzyć instancję klasy Nette\Database\Connection:

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

Parametr $dsn (Data Source Name) ma taki sam format jak PDO, np. host=127.0.0.1;dbname=test. Jeśli połączenie nie powiedzie się, zostanie wyświetlony komunikat Nette\Database\ConnectionException.

Jednak wygodniejszą metodą jest użycie konfiguracji aplikacji. Dodaj sekcję database, a zostaną utworzone wymagane obiekty, w tym panel bazy danych na pasku debugowania Tracy.

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

Następnie obiekt połączenia można pobrać jako usługę z kontenera DI, np:

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

Aby uzyskać więcej informacji, patrz konfiguracja bazy danych.

Dwa podejścia do pracy z bazą danych

W Nette Database można pisać zapytania SQL bezpośrednio (podejście bezpośrednie) lub pozwolić, aby SQL był generowany automatycznie (podejście eksploratora). Zobaczmy, jak oba podejścia rozwiązują te same zadania:

Podejście bezpośrednie – pisanie zapytań SQL

// Wstawianie rekordu
$database->query('INSERT INTO books', [
	'author_id' => $authorId,
	'title' => $bookData->title,
	'published_at' => new DateTime,
]);

// Pobieranie rekordów: autorzy książek
$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
');

// Wyświetlanie (nieoptymalne, generuje N dodatkowych zapytań)
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";
	}
}

Podejście eksploratora – automatyczne generowanie SQL

// Wstawianie rekordu
$database->table('books')->insert([
	'author_id' => $authorId,
	'title' => $bookData->title,
	'published_at' => new DateTime,
]);

// Pobieranie rekordów: autorzy książek
$authors = $database->table('authors')
	->where('active', 1);

// Wyświetl (automatycznie generuje tylko 2 zoptymalizowane zapytania)
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";
	}
}

Podejście Explorer automatycznie generuje i optymalizuje zapytania SQL. W powyższym przykładzie podejście Direct generuje N+1 zapytań (jedno dla autorów i jedno dla książek każdego autora), podczas gdy Explorer wykonuje tylko dwa zoptymalizowane zapytania – jedno dla autorów i drugie dla wszystkich ich książek.

W zależności od potrzeb można dowolnie łączyć oba podejścia w aplikacji.

Zarządzanie połączeniami

Po utworzeniu obiektu Connection automatycznie łączy się on z bazą danych. Jeśli chcesz opóźnić połączenie, włącz tryb leniwy w konfiguracji, ustawiając lazy, lub zrób to w następujący sposób:

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

Aby zarządzać połączeniem, użyj metod connect(), disconnect(), i reconnect().

  • connect() ustanawia połączenie, jeśli nie zostało jeszcze ustanowione i może rzucić Nette\Database\ConnectionException.
  • disconnect() rozłącza się z bazą danych.
  • reconnect() rozłącza się, a następnie ponownie łączy z bazą danych i może również rzucić Nette\Database\ConnectionException.

Dodatkowo można monitorować zdarzenia połączenia za pomocą zdarzenia onConnect, które jest tablicą wywołań zwrotnych wykonywanych po połączeniu z bazą danych.

// Wywoływana po połączeniu z bazą danych
$database->onConnect[] = function($database) {
	echo "Connected to the database";
};

Pasek debugowania Tracy

Jeśli używasz Tracy, panel Database na pasku debugowania jest automatycznie włączony. Wyświetla on wszystkie wykonane zapytania, ich parametry, czas wykonania i lokalizację w kodzie, w której zostały wywołane.

Obsługiwane bazy danych

Nette Database obsługuje następujące bazy danych:

Database Server DSN Name Explorer Support
MySQL (>= 5.1) mysql YES
PostgreSQL (>= 9.0) pgsql TAK
SQLite 3 (>= 3.8) sqlite TAK
Oracle oci NIE
MS SQL (PDO_SQLSRV) sqlsrv TAK
MS SQL (PDO_DBLIB) mssql NIE
ODBC odbc NIE
wersja: 4.0