ORM frameworky pro PHP5: Databázový model

V posledním díle miniseriálu o ORM knihovnách pro PHP5 si ukážeme definici databázového modelu. Příblížíme si důvody definice pro ORM frameworky a ukážeme si nástroje pro jejich zápis. Kromě obecně známých nástrojů se seznámíme i s novým nástrojem ORM Designer, který je zaměřen na ORM frameworky a nabízí plnou podporu pro frameworky Propel a Doctrine.

Seriál: ORM frameworky pro PHP (3 díly)

  1. ORM frameworky pro PHP5: Obecný úvod 27.1.2010
  2. ORM frameworky pro PHP5: Doctrine ORM 3.2.2010
  3. ORM frameworky pro PHP5: Databázový model 10.2.2010

Frameworky Propel a Doctrine jsou reprezentanty frameworků, které vyžadují zápis databázového modelu přímo do ORM. Toto je, společně s nutností zpracovat větší objem dokumentace, největší překážka pro vývojáře seznamující se s těmito frameworky. Než si ukážeme, jak zjednodušit vytváření databázových definic, objasníme si nejdříve důvody, proč je potřeba tyto definice vytvářet.

Jak již bylo řečeno v úvodu našeho seznámení s ORM frameworky, existují dva možné přístupy. Minimalistický, kdy framework nabízí velice lehké (z hlediska objemu kódu ORM frameworku) řešení a hlavním cílem je usnadnit základní opakující se úkony s databází. Komplexní frameworky se stávají naopak jádrem celé aplikace a nositelem větší části aplikační logiky. Aby mohl ORM framework nabídnout všechny funkce, které byly zmíněné v minulém článku, je nutné, aby znal strukturu databáze včetně relací.

Možnosti zápisu databázového modelu

Databázový model je možné definovat následujícími způsoby:

  • Objektový zápis (pouze Doctrine). V praxi se pro definici celého modelu nepoužívá. Používá se ale v zápisech šablon, které mohou doplnit sloupečky nebo tabulky pro chování. Dále je objektový zápis používán pro vytváření migrací (zápis změn databáze mezi verzemi aplikace).
  • Zápis pomocí popisného strukturovaného souboru (Doctrine i Propel). Oba frameworky umožňují zápis jak v jazyce XML tak i YAML (YAML Ain’t Markup Language – známý též z Ruby on Rails; na Zdrojáku vyšel článek YAML: Serializační formát pro ukládání dat – pozn. red.). Zápis v jazyce YAML je přehlednější a úpravy jsou efektivnější, proto se používá častěji než XML.

Níže je ukázka objektového zápisu tabulky Contact z minulého článku. Tato třída byla vygenerována automaticky z YAML zápisu. Metoda setTableDefinition obsahuje zápis sloupečků a jejich typů. Na konci metody byl ponechán zápis pro MySQL server s typem tabulky a znakové sady, který je možné pomocí Doctrine definovat. Metoda setUp nastavuje související relace. V našem případě se jedná o související záznamy z tabulky telefonních čísel (Phone). Na objektu Contact můžeme zavolat např. metodu $contact->getPhones() pro získání všech souvisejících záznamů. V metodě setUp je dále definice chování Timestampable.

/**
 * BaseContact
 *
 * This class has been auto-generated by the Doctrine ORM Framework
 *
 * @property integer $id
 * @property string $name
 * @property Doctrine_Collection $Phones
 *
 * @method integer             getId()       Returns the current record's "id" value
 * @method string              getName()     Returns the current record's "name" value
 * @method Doctrine_Collection getPhones()   Returns the current record's "Phones" collection
 * @method Contact             setId()       Sets the current record's "id" value
 * @method Contact             setName()     Sets the current record's "name" value
 * @method Contact             setPhones()   Sets the current record's "Phones" collection
 *
 */
abstract class BaseContact extends sfDoctrineRecord
{
    public function setTableDefinition()
    {
        $this->setTableName('contact');
        $this->hasColumn('id', 'integer', 4, array(
             'primary' => true,
             'type' => 'integer',
             'autoincrement' => true,
             'length' => '4',
             ));
        $this->hasColumn('name', 'string', 128, array(
             'type' => 'string',
             'length' => '128',
             ));
        $this->option('type', 'INNODB');
        $this->option('collate', 'utf8_czech_ci');
        $this->option('charset', 'utf8');
    }

    public function setUp()
    {
        parent::setUp();
        $this->hasMany('Phone as Phones', array(
             'local' => 'id',
             'foreign' => 'contact_id'));

        $this->actAs(new Doctrine_Template_Timestampable());
    }
}

Zápis stejné tabulky Contact pomocí YAML je na ukázce níže. Jazyk YAML má stromovou strukturu, pro odsazení se vždy používají 2 mezery (tabulátor je zakázaný). Pro oblíbené vývojářské nástroje již existují zásuvné moduly s podporou tohoto jazyka (např. YEdit pro Eclipse nebo Netbeans pro PHP a nebo Ruby). Editory pomohou se správným zápisem a především s kontrolou chyb, tím se vyhneme nepříjemnému hledání tabulátoru v souboru.

Contact:
  actAs: [Timestampable]
  columns:
    id:
      primary: true
      type: integer(4)
      autoincrement: true
    name:
      type: string(128)
  relations:
    Phones:
      class: Phone
      type:  many
      local: id
      foreign: contact_id

options:
  type: INNODB
  collate: utf8_czech_ci
  charset: utf8

Chcete se naučit o PHP víc?

Akademie Root.cz pořádá školení Kurz programování v PHP5. Jednodenní kurz programování v PHP 5 je určen všem webovým vývojářům, kteří se chtějí do hloubky seznámit a sžít s programovacím jazykem PHP ve verzi 5. První část kurzu je zaměřena na nový objektový model se všemi jeho vlastnostmi, ošetření chyb pomocí výjimek a efektivní využití těchto konceptů. Druhá část je zaměřena na nové knihovny PHP 5, především pro práci s databázemi, XML a objekty. Pozornost je věnována i zajištění kompatibility s PHP 4, přechodu z této verze a výhledu na PHP 6. Máte zájem o jiné školení? Napište nám!

Tvorba databázového modelu

Frameworky Doctrine i Propel obsahují skripty pro získání databázového modelu z existující databáze. Skripty fungují spolehlivě a načtou strukturu včetně relací. Tento způsob vytváření modelu je ale vhodný pouze pro vytvoření základu modelu. Ten je nutné ručně projít a doplnit nebo upravit názvy relací (příp. M:N relace), sloupce apod. U dalšího projektu většina vývojářů dá přednost ručnímu zápisu, protože již získá přehled o používaných značkách a časově jsou oba způsoby srovnatelné.

Díky popularitě modelovacího nástroje MySQL Workbench byl vytvořen zásuvný modul do této aplikace pro export do definic ORM frameworku. Kromě MySQL Workbench existují také konverzní skripty pro DBDesigner 4. Entitně relační modely (dále jen ER model) jsou nutností u aplikací využívajících relační databáze. Oceníme je zejména, když projekt vyvíjíme nebo se k projektu vracíme po delší přestávce. Bohužel exporty z modelovacích nástrojů trpí stejnými nedostatky jako zpětné získání definic z existující databáze. Proto je nutné udržovat ER model jak v modelovacím nástroji, tak i v textových definicích ORM frameworků. Modelovací nástroje neumožňují správu chování ani načtení ORM definic DB modelu, M:N relací nebo export jednoho modelu do více aplikačních modulů.

ORM designer

V říjnu 2009 byl veřejně uveden nástroj ORM Designer, který je zaměřen na ORM frameworky (v současnosti Propel a Doctrine). ORM Designer je vyvíjen českou firmou Inventic s.r.o. (autor článku je spoluzakladatelem společnosti – pozn. autora). ORM Designer obsahuje grafické rozhraní pro vytváření ER modelu stejně jako výše uvedené modelační nástroje. Navíc pak obsahuje:

  • Správu ORM atributů. Jak framework Doctrine, tak i Propel obsahují jinou sadu atributů. V případě Doctrine se jedná o definice chování, nastavení databázového stroje (viz. výše typ tabulky a kódování) atd.
  • Import a export do nativního formátu. ORM Designer umožňuje načíst model ze souborů XML nebo YAML s definicemi ORM frameworku. Dále pak upravený model do souborů zapíše v původním formátu (XML/YAML). U nového projektu stačí pouze zadat kořenovou složku a všechny definice jsou automaticky načteny, a to i z modulů.
  • Členění projektu do modulů. Databázový model je členěn do regionů a modulů. Regiony jsou pouze vizuální prvky pro sdružení souvisejících tabulek a relací. Modul je kromě vizuálního odlišení možné uložit do samostatného souboru v závislosti na příslušnosti k aplikačnímu modulu.
  • Podpora ORM frameworků. ORM Designer je postaven na pružné základně, která dovoluje použití s libovolným ORM frameworkem. Definice povolených hodnot grafického rozhraní (ORM atributy, datové typy sloupců apod.) je uložena v souborech XML. (Během prvního pololetí roku 2010 bude přidána podpora pro další ORM a MVC frameworky; v současnosti Symfony – pozn.aut.). Definice ER modelu je také uložena v souborech XML a dovoluje uživateli vytvořit konverzní skripty pro jiné frameworky nebo dokumentační systémy.

Na webu aplikace je kromě standardní dokumentace rozšiřující se seznam návodů na efektivní vývoj s ORM frameworky a frameworkem Symfony.

Shrnutí miniseriálu

V tomto miniseriálu jsme se seznámili s představiteli jednoho z možných přístupů k návrhovému vzoru Active Record. Cílem bylo přiblížit si frameworky, které jsou vzhledem ke své velikosti neprávem přehlíženy. Praktické zkušenosti z projektů ovšem ukazují, že i přes svou velikost a vyšší paměťovou a výpočetní náročnost mohou podávat srovnatelné výkony s aplikacemi psanými bez ORM frameworku. Navíc díky použití moderních programovacích technik dovolují agilní vývoj aplikací a extrémní programování. Stále ale platí, že se nejedná o jediný správný přístup a je nutné vybírat vhodná řešení pro daný projekt.

Komentáře: 9

Přehled komentářů

bezejmenný Zend_Db_Table
frantisek.troster Re: Zend_Db_Table
Srigi Re: Zend_Db_Table
Avatar XML vs YAML
frantisek.troster Re: XML vs YAML
František Kučera Relace vs. vztah
newman Propel vs Doctrine
frantisek.troster Re: Propel vs Doctrine
newman Re: Propel vs Doctrine
Zdroj: https://www.zdrojak.cz/?p=3162