Princip modelování
ORM DataModel má jedno důležité specifikum. Jeho hlavní funkce a smysl nespočívá pouze v mapování tříd na databázové tabulky. ORM DataModel operuje s celými entitami, které se skládají z více tříd a tedy i databázových tabulek. Celá entita se tedy skládá z jedné hlavní entity a jejích subentit, které mohou mít další vlastní subentity. S takovou entitou lze následně operovat jako s jedním celkem. Celou entitu tvořenou více tabulkami lze nahrávat a automaticky instancovat jednoduše jednou operací, stejně tak mazat a také ukládat. S samozřejmě zůstává možnost operovat i pouze s dílčími subentitami.
Mezi entitami tvořícími jeden celek pak existují tak zvané vnitřní relace. Ovšem v rámci ORM je možné provazovat tyto celky mezi sebou a vytvářet tak vnější relace.
Ukažme si to rovnou na příkladu. Jako příklad poslouží entita faktura. Datový model faktury se skládá z těchto částí:
-
Obecné informace o faktuře - hlavní entita
Tedy entita zahrnující obecné informace o faktuře jako je její číslo, datum vystavení, informace o odběrateli, datum splatnosti a tak dále ... -
Položky faktury - subentita v relaci 1:N na hlavní entitu
Každá faktura má položky. O každé položce je nutné znát její popis, cenu za jednotku, počet jednotek (kusů, hodin a tak dále), sazbu DPH, členění DPH a a tak dále. -
Informace o úhradách faktury - subentita v relaci 1:N na hlavní entitu
Rovněž je nutné evidovat úhradu / nebo úhrady faktury, jejich výše, formy úhrady a tak dále.
Na diagramu by to vypadalo takto:
Jak vidno, tak faktura se skládá minimálně ze třech tříd a třech databázových tabulek na které jsou tyto třídy mapovány. Ovšem Jet ORM DataModel umí nahlížet na fakturu jako na jeden celek. Jako celek ji umí načíst, instancovat a samozřejmě i ukládat. To vše pomocí systému vnitřních relací.
Je důležité zdůraznit, že struktura takové entity může mít vlastně libovolné množství subentit a jejich zanoření. Tedy i subentita může mít své vlastní subentity. Například položky faktury by mohly mít další subentity a ty další a tak dále. Například takto:
Jedinou podmínkou je, aby všechny subentity všech úrovní znaly identifikaci hlavní entity ke které náleží. Tedy v našem příkladě by to bylo ID faktury. Viz kapitola vnitřní relace.
V praxi se pak s fakturou operuje například takto:
$invoice = Invoice::load( [ 'invoice_id' => $invoice_id ] );
$invoice->addPayment( $new_payment_info );
$invoice->setIsPaid( true );
$invoice->save();
Nebo takto:
$invoice = Invoice::load( [ 'invoice_id' => $invoice_id ] );
foreach( $invoice->getItems() as $item ) {
//do something with the item
}
Ovšem v praxi samozřejmě pouze vnitřní relace nestačí. Naše pomyslná faktura je v praxi svázána s dalšími entitami.
Zůstaňme u našeho příkladu faktury. Kromě faktur bude součástí takového systému i seznam zákazníků - klientů a odběratelů. Součástí tohoto seznamu zákazníků bude i seznam kontaktních osob. Opět bude platit, že zákazník bude hlavní entita a na něj navázané kontakty budou subentitou vázanou vnitřní relací a to vše bude opět tvořit jeden celek.
Ovšem celá tato entita definující zákazníka a jeho kontakty samozřejmě musí být svázána s celou entitou faktura a to takto:
To je možné díky mechanismu, který je v rámci Jet ORM DataModel nazýván vnější relace.
Díky tomuto mechanismu je pak možné například snadno získat instance celých faktur třeba na základě kontaktního e-mailu zákazníka:
$invoices = Invoice::fetchInstances( ['customers_contacts.email'=>$email] );