A Doctrine alacsony szintjén a sémát php osztályok halmaza reprezentálja, amit adatbázistáblákra képezünk le. Ez a fejezet arról szól, hogyan képezzük le az osztályokat adatbázistáblákra.
Az egyik probléma, hogy az adatbázis kezelők viselkedése különböző, pl. hogy hogyan tér vissza az eredmények halmazával. A MySQL a mezők neveit változatlanul hagyja, pl ha a lekérdezés így kezdődik: "SELECT myField FROM ...", akkor az eredmények közt lesz egy myField nevű mező
Sajnos ez a MySQL és néhány más adatbázis kezelő kivételével nem így történik. Pl a Postgres az összes mező nevét kisbetűvé alakítja, míg az Oracle adatbázis kezelője mindent nagybetűsít. Szerencsére Doctrine használatával nem kell törődni ezekkel a különbségekkel.
A Doctrine elfedi ezeket a problémákat. Ez azt jelenti, hogy ha definiálunk egy származtatott Record osztályt és definiálunk egy myField nevű mezőt mindig el fogjuk érni a $record->myField (vagy $record['myField']) hivatkozáson ketesztül, nem fontos, hogy MySQL, Postgres vagy Oracle adatbázis kezelőt használunk.
Röviden: Úgy nevezed a mezőidet, ahogy kedved tartja, tartalmazhat aláhúzás_jelet, lehet camelCase vagy amit szeretsz. Azt azért figyelembe kell venni, hogy a Doctrine case sensitive.
Doctrine-ban a mezőknek van egy hossz tulajdonsága. Néha ettől a számtól függ egy mező típusa. Pl. egy 1000 hosszúságú string mysql-re képezve TEXT lesz VARCHAR helyett.
A hossz a következő típusoknál fontos tényező:
A Doctrine lehetőséget ad álnevet adni az oszlopoknak. Ez akkor hasznos, ha az alkalmazáslogikát és az adatbázis logikát függetleníteni szeretnénk egymástól. Pl. ha meg szeretnéd változtatni az adatbázis mezőinek a nevét, az alkalmazásban csak a definíciókat kell módosítanod.
Ugyanez a példa YAML fájl használata esetén:
Most az adatbázisban bookTitle a mező neve, míg az objektumban title néven érjük el ezt a tulajdonságot.
Doctrine-ban minden adattípusnak van saját alapértelmezett értéke. Ha alapértelmezett értéket adunk egy mezőnek, az két dolgot jelent: Ez lesz az alapértelmezett értéke minden újonnan létrehozott Record-nak, és amikor a Doctrine legenerálja az adatbázistáblát, ez lesz az alapértelmezett érték a tábla definícióban is.
Az előző példa YAML fájl használata esetén:
Ha most létrehozunk egy új User példányt, az alapértelmezett username kerül kiírásra:
Az adatbázis kezelők több lehetőséget nyújtanak az adatok tárolására, amit a táblákban tárolhatunk. Az adattípusok lehetőséget adnak áttérni más adatbázis kezelőre.
Hogy egyszerűbb legyen az együttműködés adatbázis kezelőkkel, adattípusok egy halmaza előre van definiálva. Az alkalmazások gyártófüggetlenül érik el ezeket.
A Doctrine ügyel az adattípusokra amikor az objektumokat adattáblákra map-peli. Adatok írása és olvasása közben az adatbázis kezelő drivere konvertál.
A következő adattípus példák a Doctrine createTable() metódusával használhatók.
Az adattípusok fejezet végén levő példatömb a createTable() metódussal használandó, arra, hogy a válaszott adatbázis kezelőn
egy hordozható táblát készítsünk( A Doctrine dokumentációban szerepel, hogy mely adatbázis kezelők támogatottak ).
Megjegyzendő, hogy a következő példák nem fedik le az indexek készítését és a karbantartását, ez a fejezet csak az adattípusokkal
és azok helyes felhasználásával foglalkozik.
Megjegyzendő, hogy az oszlopok hossza befolyással van az adatbázis szint típusára, csakúgy, mint az elfogadási szint hosszára(az a hossz, ami a Doctrine validátorokkal van validálva).
1. Példa: A 'content' nevű oszlop 'string' típussal és 3000 hosszal az adatbázisban 'TEXT' típust eredményeznek, aminek az adatbázisban 4000 a hossza. Ennek ellenére az alkalmazásban a 'content'-oszlop hossza maximum 3000 lehet.
2. Példa: Egy 1 hosszú 'integer' típusú oszlop a legtöbb adatbázis kezelőben 'TINYINT' mezőt eredményez.
A Doctrine általában elég okos ahhoz, hogy kitalálja, hogy melyik integer/string típus szükséges a hossztól függően.
A Doctrine API-ban szerepel néhány opcionálisan használható módosító:
Doctrine-ban a táblák összekapcsolását a Doctrine_Record::hasMany, Doctrine_Record::hasOne műveletekkel adhatjuk meg. A Doctrine támogatja az összes kapcsolatot az egyszerű one-to-one idegenkulcsos kapcsolattól a self-referencing kapcsolatig bezárólag.
Az oszlopdefiníciókkal ellentétben a Doctrine_Record::hasMany és a Doctrine_Record::hasOne a setUp()-on belül helyezkednek el. Mindkettőnek két argumanentuma van: az első az osztály nevét és esetleg egy álnevet tartalmaz, a második argumentum egy tömb, ami a kapcsolat beállításait tartalmazza. Ezek a következők lehetnek:Nézzünk egy példát: Van két osztályunk, a Forum_Thread és a Forum_Board. A Forum_Board több Forum_Thread-et tartalmaz, ezért one-to-many kapcsolatot használunk. Figyeljük meg, hogy a Forum_ előtagot elhagyva létrehozunk egy Threads nevű aliast.
Először nézzük a Forum_Board osztályt. Három oszlopa van: name, description És egy id nevű elsődleges kulcs, amit a Doctrine automatikusan hozott létre.
Kapcsoljuk össze a Forum_Thread osztállyal, ezzek a hasMany() metódust használjuk. a local mező az osztály elsődleges kulcs id mezője, amit a Doctrine hozott létre, a foreign mező pedig a board_id mező a Forum_Thread osztály mezője.
A fenti példa YAML használatával:
Lássuk a Forum_Thread osztályt. Az oszlopok nem lényegesek, csak a kapcsolatok. Minden Thread-nek csak egy Board-ja van, ezért a hasOne() metódust használjuk. Itt is adunk állnevet, a Forum_Board helyett Board-ot. Itt a local oszlop a board_id, míg a foreign oszlop az id.
Ugyanez YAML-al:
Most már használhatjuk az osztályokat.
Hozzunk létre egy új board-ot
Adjunk egy új thread-et a board-hoz:
Minden Thread-hez tartozik egy felhasználó, hozzunk létre tehát egy új User-t, és kapcsoljuk a Thread-hez:
Most mentsünk ki mindent egyetlen metódushívással. Ezzel mindent mentünk adatbázisba
Végezzünk ellenőrzést, nézzük meg az adatszerkezetet, ami létrejön a fenti kód hatására: