Článek v rubrikách:

»PHP
»MySQL
»Dibi

DbDibiOrm - DibiConnection - staticky, instančně, přistupovat přímo k dibi factory?

Jeden díl ze série článků o stavbě ORM postaveném nad dibi. Jak pracovat s konekcí k databázi? Jak DibiConnection získávat a kde ho ukládat?


Tuto otázku řešíte i mimo ORM. Máte sadu modelů s metodami, které přistupují k databázi, tedy využívají DibiConnection.

Jak ale k samotné instanci budete přistupovat?

  1. class BaseModel {
  2. public static function find($id) {
  3. $db=získej !! ve static kontextu !! proměnnou DibiConnection
  4. $db->select(.....);
  5. }
  6. public function insert($data) {
  7. $db->insert(.....);
  8. }
  9. }

Budete tedy volat globální továrnu přímo v metodách insert a find? Tedy dibi::getConnection()? Nebo budete volat static::getDbConnection() (jak to dělá většina ORM frameworků)?

K čemu je vlastně mít vlastní instanci připojení k databázi v konkrétním modelu?

Jediné co mne napadá: Abychom se mohli připojovat k více databázím a tedy využívali stejných objektů? Tedy všechny zůčastněné databáze budou muset mít stejnou strukturu, prostě budou totožné? A ještě proměnnou musíme měnit v globálním statickém kontextu. Tedy, abychom s modelem Customer mohli pracovat v jiné databázi musíme podědit, a vytvořit Db1Customer extends BaseModel, Db2Customer extends BaseModel?

Jak to tedy je? Je to k něčemu použitelné?

U Ormionu mi ještě nesedí, že je to naopak svázané s třídou Ormion, tzn. stejně to nelze změnit a je připojení pevně dané, je to tedy stejné jako volat globální proměnnou napřímo.

  1. class Ormion
  2. ...
  3. protected static function getDb() {
  4. if (!self::$db) {
  5. self::$db = new DibiConnection(Environment::getConfig("database"));
  6. }
  7. return self::$db;
  8. }

Zajímavé zdroje (Dependency Injection a Singleton je zlo)

  1. Singletons are pathological liars
  2. Je singleton zlo?
  3. Where Have All the Singletons Gone?

Je reálné zaměnit instanci připojení k databázi?

Zajímalo, by mne co si myslíte o tom, jestli Dependency Injection má v tomto případě smysl? Považte, že celé ORM je závislé na dibi, využívá DibiFluent a tedy nemá smysl zaměňovat za jiný layer. ORM je stavěné na dibi! Pokud chceme například pro účely testování zaměnit databázi pro zápis, můžeme tak učinit v globální továrně dibi, případně před provedením konkrétního požadavku mohu na určitou část kódu zaměnit výchozí, tedy poslední použité připojení k databázi.

Ale má to smysl dělat to u konkrétní instance objektu? Představte si tento příklad:

  1. $customer=new Customer();
  2. $customer->setDbConnection(dibi::getConnection('anotherDatabase'));
  3. $customer->email="test@email.cz";
  4. $cusotmer->save();

Co když Customer před uložením kontroluje jeslti se jednoznačný identifikátor (email) nenachází v tabulce reader? Pokud ano, vyhodí upozornění, zda nechceme účty spojit? Zda se nejedná o stejného člověka? Nebo naopak nedovolí vůbec uložit zákazníka, který existuje jako čtenář. Pouze hypotéza! Kde budeme čtenáře hledat? V anotherDatabase nebo defaultDatabase? To dáme objektu Reader také vědět že by měl změnit connection? Je tedy vůbec logické měnit connection jednotlivé instanci? A další dotaz je vůbec logické měnit modelu připojení databázi jinak než globálně?

podobné články

09.12.2009DbDibiOrm(50%)