Databáze
Nette Framework nám poskytuje vrstvu pro výrazně pohodlnější práci s databázemi. Co umí?
- snadno skládat SQL dotazy
- snadno získávat data
- pokládá efektivní dotazy a nepřenáší zbytečná data
Nette Database Core tvoří obálku nad PDO a poskytuje základní funkcionalitu pokládání dotazů.
Nette Database Explorer poskytuje pokročilou a efektivní práci s tabulkami.
Vytvoření připojení
Pro vytvoření nového připojení k databázi stačí vytvořit novou instanci třídy Nette\Database\Connection. To provedeme buď pomocí aplikační konfigurace nebo v případě, kdy používáme Nette\Database samostatně, následovně:
use Nette\Database\Connection;
$connection = new Connection($dsn, $user, $password);
Více informací v odstavci pokročilé nastavení spojení
Vytvoření pomocí aplikační konfigurace
Nejjednodušším způsobem, jak nastavit připojení k databázi, je v aplikační
konfiguraci, která umožňuje vytvoření více připojení a také usnadňuje přidání panelu databáze do Tracy debugger
baru. Tento zápis vytvoří krom Nette\Database\Connection
také službu Nette\Database\Context
, která
je nutná pro práci s vrstvou Database\Table.
database:
default:
dsn: "mysql:host=127.0.0.1;dbname=test"
user: "root"
password: "password"
options:
lazy: true
Více informací v odstavci pokročilé nastavení spojení
Dotazy
Database\Connection umožňuje jednoduše pokládat databázové dotazy voláním metody query
, která nám vrací
ResultSet.
$connection->query('INSERT INTO users', array( // parametr může být pole
'name' => 'Jim',
'created' => new DateTime, // nebo objekt DateTime
'avatar' => fopen('image.gif', 'r'), // nebo soubor
), ...); // je možné také provést více vložení najednou
$connection->query('UPDATE users SET ? WHERE id=?', $data, $id);
$result = $connection>query('SELECT * FROM users WHERE id=?', 123);
//ResultSet implemetuje iterator
foreach ($result as $row) {
echo $row['name'];
}
$rows = $result->fetch(); //vrátí následující řádek nebo FALSE
$rows = $result->fetchAll(); //vrátí všechny řádky jako pole
Nad třídou ResultSet
je možné iterovat pouze jednou, pokud potřebujeme iterovat vícekrát, je
nutno tento objekt převést na pole metodou fetchAll()
Podporované databáze
Nette\Database si vytvoří vlastní vnitřní ovladač a nastaví své chování podle toho, jaký používáte databázový server. Nette podporuje následující databáze:
Databázový server | DSN jméno | Podpora v Core | Podpora v Explorer |
---|---|---|---|
MySQL | mysql | ANO | ANO |
PostgreSQL | pgsql | ANO | ANO |
Sqlite 3 | sqlite | ANO | ANO |
Sqlite 2 | sqlite2 | ANO | – |
Oracle | oci | ANO | – |
MS SQL (PDO_SQLSRV) | sqlsrv | ANO | ANO |
MS SQL (PDO_DBLIB) | mssql | ANO | – |
ODBC | odbc | ANO | – |
Pokročilé nastavení spojení
Volitelný čtvrtý parametr konstruktoru Connection umožňuje přidat dodatečné parametry. Tyto volby jsou předány jak konstruktoru PDO, tak vnitřnímu ovladači, mohou tedy obsahovat konfiguraci pro instanci PDO i pro instanci ovladače.
Připojení může být vytvořeno „líně“. To znamená, že připojení k databázi je navázáno až ve chvíli, kdy je
poprvé potřeba, ne když je vytvořena instance Connection
. Toto chování můžeme zapnout přidáním konfigurace
'lazy' => TRUE
.
Ovladač databáze je zvolen podle použitého DSN jména. Můžeme ale poskytnout vlastní implementaci ovladače. To
uděláme předáním jména ovladače jako hodnoty parametru driverClass
.
$connection = new Connection($dsn, $user, $password, array(
'lazy' => FALSE,
'driverClass' => 'App\JmenoVasiVlastniImplementaceOvladace'
));
V běžné Nette aplikaci, kde používáme celé Nette a nikoliv jen samostatnou databázovou vrstvu, vytváříme vždy spojení pomocí aplikační konfigurace. Ta je velmi intuitivní a umožní nám také snadno používat vrstvu Database\Table:
database:
default:
dsn: "mysql:host=127.0.0.1;dbname=test"
user: "root"
password: "password"
options:
PDO::MYSQL_ATTR_COMPRESS: true
lazy: true
debugger: true # panel v debugger baru
explain: true # explain dotazů v debugger bar
conventions: discovered # nebo static nebo vaší jméno třídy, výchozí je discovered
autowired: true # defaultní u prvního spojení
anotherConnection:
dsn: ...
autowired: false #defaultní u druhého a dalšího spojení
Práce se databázovými službami
Každé takto definované spojení vytvoří dvě služby – Nette\Database\Connection
pod názvem
database.[NAME].connection
(tedy např. database.default.connection
) a
Nette\Database\Context
pod názvem database.[NAME].context
(např.
database.default.context
).
Pokud si při práci s databází vystačíme s psaním SQL dotazů, jako jsme viděli v této kapitole, bude nám stačit
první jmenovaná služba. Pokud však chceme využívat všechny možnosti vrstvy Database\Table, musíme pracovat se službou
Context
.
V případě, že používáme pouze jedno databázové spojení, nemusíme se o nic starat a vyžádáme si jej pomocí DI.
class UserManager
{
private $connection;
public function __construct(Nette\Database\Connection $connection)
{
$this->connection = $connection;
//nebo si vyzadame Nette\Database\Context, pokud chceme pracovat s Database\Table
}
}
Jestliže však máme definováno více spojení, je nutné ta spojení, která nejsou autowirovaná (obvykle druhé a následující) předat ručně v konfiguraci:
services:
- UserManager(@database.anotherConnection.connection) #nebo @database.anotherConnection.context