Doctrine (PHP)
Author
Albert FloresDoctrine je ORM framework pro jazyk PHP. Nabízí vysokou míru abstrakce databázové vrstvy použitím objektového přístupu. Umožňuje tak pracovat s daty jako s objekty. Jedna z klíčových vlastností Doctrine je psaní databázových dotazů použitím [url=https://web.archive.org/web/20100527214239/http://www.doctrine-project.org/documentation/manual/1_1/en/dql-doctrine-query-language]Doctrine Query Language (DQL)[/url], který vychází z ORM frameworku Hibernate určeným pro Javu. Doctrine je šířen pod licencí LGPL.
Struktura frameworku
Framework Doctrine je rozdělen do tří vrstev.
* Common Obsahuje obecná rozhraní, třídy a knihovny (práce s kolekcemi, anotacemi, cachování). Vrstva je na ostatních dvou vrstvách nezávislá, ale Common vrstvu ostatní vrstvy používají.
* DBAL (DataBase Abstraction Layer) Zajišťuje databázovou nezávislost. Definuje DQL (Doctrine Query Language). Je závislá na vrstvě Common.
* ORM (Object-Relational Mapping) Jedná se o nejvyšší vrstvu a zajišťuje mapování objektů do relační databáze, jejich ukládání a načítání.
Požadavky
Doctrine pro svůj běh vyžaduje minimálně PHP 5.3 (pro Doctrine 2). Podporuje tyto databáze:
* MySQL a MariaDB * PostgreSQL * Oracle * SQLite * Drizzle * SAP Sybase SQL Anywhere * Microsoft SQL Server
Výhody
Výhodou Doctrine je nízká náročnost na konfiguraci. Doctrine umí generovat object-class z existující databáze, programátor pak již pouze specifikuje vazby mezi entitami a další funkce. +more Na rozdíl od jiných ORM frameworků Doctrine nepracuje se složitým popisem databázového schématu pomocí XML, ale v případě potřeby je možno použít i XML popis.
Doctrine je postavena na návrhovém vzoru Data Mapper (na rozdíl od jiných ORM frameworků, které vycházejí z návrhového vzoru Active Record). K definici databázových entit se využívá komentářové anotace. +more Podle návrhového vzoru Data Mapper objekt neobsahuje žádné operace. O tyto operace se stará oddělený objekt (v případě Doctrine je to třída EntityManager). Tímto přístupem je zajištěna nezávislost na databázi.
Další výhody: * Podpora stromových struktur dat * Výchozí použití transakcí u databází, které je podporují * Databázová nezávislost * Komentářová anotace * Optimalizace výkonu (cachování na několika úrovních)
Definice a práce entitami
Entita je základní kámen Doctrine a vůbec objektového mapování. Reprezentuje objekt reálného světa. +more Zjednodušeně si lze entitu představit jako jeden řádek v databázové tabulce. Entitou může být např. student, učitel, předmět.
Příklad definice entity:
id; }
public function getJmeno: string { return $this->jmeno; }
public function setJmeno(string $jmeno): void { $this->jmeno = $jmeno; }
public function getPrijmeni: string { return $this->prijmeni; }
public function setPrijmeni(string $prijmeni): void { $this->prijmeni = $prijmeni; } }
Takto jsme nadefinovali entitu student se třemi atributy: id, jméno a příjmení. Při této definici jsme použili tzv. +more komentářovou anotaci. Druhý způsob definice entity vede přes XML nebo YAML soubory. Atribut id je primární klíč a jeho hodnota se automaticky generuje. Jako název tabulky a jejich sloupců se defaultně použijí názvy entit a jejich členských proměnných. Toto chování lze změnit uvedením atributu anotace name. S entitou se pak pracuje stejně jako s jakýmkoli jiným objektem. K ukládání nových entit a vyhledávání slouží třída EntityManager, jejíž instance je zavedena při startu aplikace. Příklad vytvoření nové entity a hledání:.
setJmeno('Franta'); $student->setPrijmeni('Vomáčka');
echo $student->getJmeno; echo $student->getPrijmeni;
$entityManager->persist($student); // persistuje entitu a vytvoří ID $entityManager->flush($student); // uloží fyzicky do DB
// vyhledání studenta s id=5 $student2 = $entityManager->find('Student', 5);
echo $student2->getJmeno; echo $student2->getPrijmeni;
// změna a uložení $student2->setJmeno('Jaromir'); $entityManager->flush; // Uloží všechny změny
Příklad ukazuje základní vlastnosti objektového mapování, kdy s daty pracujeme jako s objektem a veškeré změny jsou přenášeny do databáze. Místo ukládání entit se v Doctrine používá výraz persistence. +more Důvod je spíš filozofický a vychází z významu slov, persistovat entitu můžeme jenom jednou a to po vytvoření nové instance.
Příklad smazání entity:
$entityManager->remove($student); // Odebere entitu v UnitOfWork $entityManager->flush; // Provede fyzické odebrání v databázi
Metodě remove je předána instance entity, kterou chceme smazat.
DQL
DQL (Doctrine Query Language) je dotazovací jazyk pro použití s frameworkem Doctrine. Je podobný jako SQL, ale vychází z jiných principů. +more Koncepčně vychází z Hibernate Query Language (HQL) a z Java Persistence Query Language (JPQL). Nejsilnější stránkou DQL je kombinace jednoduchosti SQL a nezávislosti objektové vrstvy.
Výsledkem DQL dotazu není jako v případě SQL tabulka s řádky, ale načtené instance entit. Při vytváření DQL dotazu vycházíme z definovaných názvů entit a jejich členských proměnných. +more Takto jsme zcela oproštěni od samotné existence databázových tabulek. Tím, že při definici entit jsme popsali vazby mezi nimi, výsledkem dotazu bude odkaz na asociaci, kterou jsou entity v dotazu propojeny.
S DQL je možno provádět operace SELECT, UPDATE, DELETE. Příkazy GRANT, ALTER, CREATE, DROP nelze provést, protože je to v rozporu se základní myšlenkou Doctrine (tyto příkazy se týkají přímo fyzické vrstvy). +more Základní dotaz: $query=$entityManager->createQuery("SELECT s FROM Project\Model\Student s WHERE s. jmeno = 'Franta'"); //pole objektů Student $results=$query->getResult; V tomto dotazu jsme použili alias pro entitu Student. Cestu k entitě definuje namespace entity.
Dotaz s využitím spojení tabulek:
$query = $entityManager->createQuery('SELECT a FROM Article a JOIN a.user u ORDER BY u.name ASC'); // pole objektů Article $articles = $query->getResult;
Při spojování tabulek nemusíme uvádět, kterých sloupců se to týká, protože to framework rozpozná sám díky již nadefinovaným asociacím.
Dotaz využívající pojmenované parametry:
$query = $entityManager->createQuery('SELECT u FROM User u WHERE u.username = :name'); $query->setParameter('name', 'Franta'); $users = $query->getResult;
Kromě tohoto běžného použití DQL má programátor možnost vytvořit dotaz postupným voláním jeho metod a vytvořit tak specifický databázový dotaz. K tomu slouží třída Doctrine\ORM\QueryBuilder. +more V konečné fázi je možno použít čisté SQL, ve všech třech případech dotazů (DQL, QueryBuilder, SQL) dojde k předání výsledné instance na entitu.
Omezení
Omezení vycházejí z podstaty jazyka PHP. Jedním z nich je, že PHP je typově slabý jazyk, takže nekontroluje datový typ proměnných. +more Programátor tak musí tuto skutečnost brát v úvahu a provádět validaci dat.
Dalším omezením, které ale spíše patří do kategorie programátorských zlozvyků, je definici členských proměnných jako public. V tomto případě může dojít k neočekávanému chování aplikace.
Programátor dokonce ani nemusí definovat gettery a settery, ty slouží pouze pro vnější komunikaci s entitou. Doctrine ale dokáže s entitou komunikovat i bez nich, opět to souvisí s omezeními jazyka PHP.
Rovněž se nedoporučuje klonování a serializace entit. Může dojít k neočekávanému chování.
Související články
Externí odkazy
[url=http://www. doctrine-project. +moreorg]Domovská stránka projektu Doctrine[/url] * [url=https://web. archive. org/web/20110726002241/http://www. doctrine-project. org/documentation]Dokumentace projektu[/url] * [url=https://web. archive. org/web/20110704112014/http://www. doctrine-project. org/projects/orm/download]Stažení zdrojových kódů[/url] * [url=https://web. archive. org/web/20110605081012/http://www. doctrine-project. org/docs/orm/2. 0/en/#cookbook]Příklady použití Doctrine[/url] * [url=http://zdrojak. root. cz/serialy/doctrine-2]Seriál na serveru root. cz[/url].