SilverStripe und ORM

Hinter jedem CMS steht immer eine Datenbank, die zu speichern der Daten, die ein Benutzer eingibt, dient. In SilverStripe geschieht dies durch objektrelationales Mapping (ORM), das heißt der Programmierer arbeitet nicht mit SQL-Strings sondern mit Objekten. Diese Objekte oder auch Datensätze heißen in SilverStripe „DataObject".

Dabei entspricht eine Klasse einer Tabelle,
eine Instanz der Klasse (Objekt) einer Zeile dieser Tabelle
und eine Eigenschaft der Klasse einer Spalte der Tabelle.

Der Vorteil für den Programmierer besteht jetzt darin, dass er erstens nicht ständig zwischen PHP und MySQL Syntax wechseln muss und zweitens muss er nicht ständig zwischen Objektorientierung und Tabellendenken abstrahieren. Wenn man das verinnerlicht hat, ist man der Glückseeligkeit wieder ein Stück näher gerückt.

Möchte man beispielsweise alle Zeilen der Tabelle „Object1" in ein Array laden geht man wie folgt vor:

$objects = DataObject::get(`Object1`);

So einfach geht das.

Für SilverStripe ist ORM kein Gesetz und so muss auch der SilverStripe Programmierer hin und wieder ein paar MySQL-Queries schreiben. Jetzt will man oft Objekten nach bestimmten Werten filtern, beispielsweise bei einer Suche. Der zweite Parameter der Methode get() ist ein String, der in die WHERE-Klausel eingesetzt wird. Hier muss jetzt SQL geschrieben werden:

$objects = DataObject::get(`Object1`, `objectProperty =`$value``);

Ausgabe im Template

Die Ausgabe des Ergebnisses im Template ist genau so einfach. Nehmen wir einmal an $objects ist der Rückgabewert einer Controller-Methode namens "Results", dann würde der Templatecode so aussehen:

<% control Results %>



$property1



$property2



<% end_control %>

Die Eigenschaften der Objekte lassen sich innerhalb dieser Schleife direkt ansprechen.

Normalisieren von Daten

Relationen zwischen Datensätzen sind in SilverStripe sehr schnell hergestellt. Folgende Definition für eine 1:1 Relation kommt ins Model:

static $has_one = array('someRelationName'=>'Object2');

Was passiert auf der Datenbankebene? Die Tabelle des Object1 bekommt einfach eine neue Spalte 'Object2ID'.

static $many_many = array('someRelationName'=>'Object2');

Jetzt wurde eine n:m Relation definiert. Hierbei kommt man nicht mehr mit einer zusätzlichen Spalte aus. Es wird eine neue Tabelle angelegt(Relation_table), die die Beziehungen zwischen Object1 und Object2 festhalten.

Filtern nach Werten aus einer Relation

Möchte man DataObjects nach dem Wert einer many_many Relation filtern, muss man die Tabellen des Objects(Object1), der Relation(Relation_table) und des in Relation stehenden Objects(Object2) verbinden(JOIN). Object hat eine Eigenschaft (object1Property), die einer Spalte der Relation(relation1) entspricht. Die zweite Spalte(relation2) der Relation entspricht nun einer Eigenschaft des in Relation stehenden Objects(object2Property). Der (doppelte) JOIN wird im vieren Parameter von DataObject::get() definiert und sieht so aus:

LEFT JOIN Relation_table ON relation1 = object1Property
LEFT JOIN Object2 ON object2Property = relation2

Im zweiten Parameter von DataObject::get() kann man nun nach einem beliebigen Parameter aus Object2 filtern:

`Object2.someParameter = `$value``

Der Rückgabewert von DataObject:get() ist immer noch ein DataObjectSet, das aus Instanzen von Object1 besteht. Es können darin also keine Eigenschaften von Object2 referenziert werden.

 

Tags: