Der Aufbau des Projektes beginnt mit dem Model. Dafür werden Klassen angelegt, die die Entitäten, also die Daten, des Programmes darstellen. Gleichzeitig wird ein OR-Mapping durchgeführt, so dass die einzelnen Variablen dieser Klasse Entsprechungen in Datenfeldern innerhalb der Datenbank finden. Das OR-Mapping erledigt Symfony nicht selbst, sondern es greift hier auf eine Bibliothek namens Doctrine zurück. Diese Bibliothek ist als Abhängigkeit in unserem neuen Projekt von Symfony als Standardabhängigkeit schon vorkonfiguriert worden.
Für das Buchregal-Projekt soll eine MySQL-kompatible Datenbank genutzt werden. In der Datei parameters.yml
innerhalb des Verzeichnisses \app\config\
wird die Datenbankverbindung konfiguriert. Hier muss Nutzername und Passwort für den Login in die Datenbank hinterlegt werden. Die Datenbank, in welcher die Informationen des Bücherregals abgelegt werden, wird buchregal
genannt. Sobald alle Einstellungen hinterlegt worden sind, kann Doctrine die Datenbank selbständig anlegen, indem das Konsolenkommando
1 |
php bin/console doctrine:database:create |
genutzt wird.
Die Applikation basiert auf drei Entitäten:
- den Büchern,
- den Entleihern und
- einer Verknüpfung zwischen beiden, der Verleihung.
Für die drei Entitäten wird mit Hilfe von Doctrine jeweils eine die Entitäts-Klasse und die Repository-Klasse, die als Data Access Object (DAO) dient, erstellt:
1 2 3 |
php bin/console generate:doctrine:entity --entity=AppBundle:Buch --fields="autor:string(length=100 nullable=false unique=false) titel:string(length=100 nullable=false unique=false)" --no-interaction --format=annotation php bin/console generate:doctrine:entity --entity=AppBundle:Entleiher --fields="username:string(length=100 nullable=false unique=false) email:string(length=100 nullable=false unique=true) password:string(100)" --no-interaction --format=annotation php bin/console generate:doctrine:entity --entity=AppBundle:Entleihung --fields=" voraussichtlicheRueckgabeAm:datetime(nullable=false) rueckgabeAm:datetime(nullable=true)" --no-interaction --format=annotation |
Bei einem Blick in das Verzeichnis \src\AppBundle\Entity\
sind die Entitäts-Klassen zu finden. Die Repository-Klassen sind unter \src\AppBundle\Repository\
angelegt worden.
Die entstandenen Entitäts-Klassen besitzen zum einen die angegebenen Felder als Variablen. Zusätzlich dazu besitzen die Felder in Kommentaren eingebettete Annotationen, die Doctrine darüber Auskunft geben, wie diese Variablen in die Datenbank abgebildet werden sollen. Jede Entitäts-Klasse wird mit der @Entity
-Annotation als eine solche markiert. Zusätzlich zu dieser Annotation ist angegeben, wo die Repository-Klasse zu finden ist. Die Annotation @Id
sorgt dafür, dass die Variable als Schlüssel in der Datenbank genutzt wird. Die Annotation @GeneratedValue
sorgt dafür, dass dem Datenbankmanagementsystem überlassen wird, wie der Wert generiert wird.
Leider ist das OR-Mapping noch nicht vollständig. Über den Generator kann keine Verbindung zwischen den einzelnen Klassen hergestellt werden. Aus diesem Grunde wird in den drei Entity-Dateien nun die Verknüpfung manuell eingefügt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php // Buch.php // ... /** * @var Entleihung[]|ArrayCollection * * @ORM\OneToMany(targetEntity="Entleihung", mappedBy="buch", orphanRemoval=true) * @ORM\OrderBy({"voraussichtlicheRueckgabeAm": "DESC"}) */ private $entleihungen; public function __construct() { $this->entleihungen = new ArrayCollection(); } // ... ?> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php // Entleihung.php // ... /** * @var Buch * * @ORM\ManyToOne(targetEntity="Buch", inversedBy="entleihungen") * @ORM\JoinColumn(nullable=false) */ private $buch; /** * @var Entleiher * * @ORM\ManyToOne(targetEntity="Entleiher") * @ORM\JoinColumn(nullable=false) */ private $entleiher; /** * Set buch * @param string buch * @return Entleihung */ public function setBuch($buch) { $this->buch = $buch; return $this; } /** * Set entleiher * @param Entleiher entleiher * @return Entleihung */ public function setEntleiher($entleiher) { $this->entleiher = $entleiher; return $this; } public function getEntleiher() { return $this->entleiher; } // ... ?> |
1 2 3 |
<?php // Entleiher.php // keine Änderung ?> |
Zwischen der Buch-Entität und der Entleihungs-Entität befindet sich eine One-to-Many-Beziehung. Ein Buch kann mehrfach verliehen werden. Aus der anderen Richtung her ist diese Beziehung allerdings als eine Many-to-One-Beziehung zu betrachten. Eine konkrete Verleihung betrifft nur ein Buch. Zwischen dem Buch und der Entleihung wird eine bidirektionale Verbindung aufgebaut. Das bedeutet, von beiden Seiten kann die jeweils andere Seite bestimmt werden. Innerhalb des Buch-Objektes muss hier eine Liste von Objekten vorgehalten werden. Innerhalb des Entleih-Objektes reicht eine einfache Referenz auf das geliehene Buch. Ebenso besteht eine Many-to-One-Beziehung zwischen der Entleihungs-Klasse und dem Entleiher. Ein Entleiher darf mehrere Bücher entleihen. Anders als die erste Beziehung ist diese jedoch nur unidirektional Verfolgbar. Nur das Entleihungsobjekt hält eine Referenz auf den Entleiher.
Nun lassen sich die Entitäts-Klassen mit dem Kommando
1 |
php bin/console doctrine:schema:validate |
validieren. Ist diese Validierung erfolgreich, kann aus den Klassen heraus das Datenbankschema mit dem Befehl
1 |
php bin/console doctrine:schema:update --force |
generiert und in die Datenbank geschrieben werden.
Mit Hilfe von phpMyAdmin kann nun das Datenbankschema geprüft werden. Während der Prüfung sollten einige Bücher sowie ein Test-Nutzer mit Hilfe der in phpMyAdmin integrierten Eingabemasken angelegt werden.