Entity konfigurieren
Hier werden die Konfigurationsmöglichkeiten von Entities beschrieben.
Id
Ist nichts weiter definiert, wird angenommen, dass die Eigenschaft mit Namen "id" die Id (Primary Key) repräsentiert und das der Wert der zugehörigen Spalte von der Datenbank automatisch generiert wird (in MySQL
AUTO_INCREMENT
n2n\\persistence\\orm\\annotation\\AnnoId
class User extends EntityAdapter {
private static function _annos(AnnoInit $as) {
$as->p('name', new AnnoId());
}
private $name;
private $password;
// getters / setters
}
Über die Parameter von
AnnoId
Tabellen- und Spaltennamen
Wird nichts weiter konfiguriert, werden standardmässig Klassen- und Eigenschaftsnamen "hyphenated" und diese als Tabellen- und Spaltennamen verwendet. Für eine Entity mit Klassennamen
BlogArticle
blog_article
$orderIndex
order_index
n2n\\persistence\\orm\\annotation\\AnnoTable
n2n\\persistence\\orm\\annotation\\AnnoColumn
class BlogUser extends EntityAdapter {
private static function _annos(AnnoInit $ai) {
$ai->c(new AnnoTable('bloguser'));
$ai->p('firstName', new AnnoColumn('firstname'));
}
private $id;
private $firstName;
private $lastName;
// getters / setters
}
Für die Entity
User
CREATE TABLE `bloguser` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`last_name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) COLLATE='utf8_general_ci' ENGINE=InnoDB;
Naming Strategy
Du kannst den Algorithmus zum Generieren von Tabellen- und Spaltennamen überschreiben, indem du eine eigene "Naming Strategy" definierst. Hierzu musst du eine Klasse erstellen, die
n2n\\persistence\\orm\\model\ amingStrategy
[orm]
[orm]
naming_strategy = \"atusch\\config\\CustomNamingStrategy\"
Du kannst auch eine der Implementationen verwenden, die n2n zur Verfügung stellt:
- (Standard)
n2n\\persistence\\orm\\model\\HyphenatedNamingStrategy n2n\\persistence\\orm\\model\\IdenticalNamingStrategyn2n\\persistence\\orm\\model\\LowercasedNamingStrategy
Über die Annotation
n2n\\persistence\\orm\\annotation\\AnnoNamingStrategy
class User extends EntityAdapter {
private static function _anno(AnnoInit $ai) {
$ai->c(new AnnoNamingStrategy(new LowercasedNamingStrategy()));
}
// class body
}
Achtung: Definierst du eine eigene "Naming Strategy" in der
app.ini
AnnoNamingStrategy
Mapped Supperclass
Du kannst Eigenschaften in sogenannte "Mapped Superclasses" auslagern, die von Entities erweitert werden können. Die Eigenschaften werden dabei in der Tabelle der Entity gespeichert, als wären sie in ihr selbst definiert. "Mapped Superclasses" müssen mit
n2n\\persistence\\orm\\annotation\\AnnoMappedSuperclass
app.ini
class Teaser extends ObjectAdapter {
private static function _annos(AnnoInit $ai) {
$ai->c(new AnnoMappedSuperclass());
}
private $title;
private $description;
public function getTitle() {
return $this->title;
}
public function setTitle($title) {
$this->title = $title;
}
public function getDescription() {
return $this->description;
}
public function setDescription($description) {
$this->description = $description;
}
}
Teaser
class News extends Teaser {
private $id;
private $text;
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getText() {
return $this->text;
}
public function setText($text) {
$this->text = $text;
}
}
Zur Entity
News
CREATE TABLE IF NOT EXISTS `news` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(50),
`description` VARCHAR(255),
`text` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Embedded
Du kannst Eigenschaften auch in eine Extraklasse auslagern und deren Objekte per Eigenschaft referenzieren. Solche Eigenschaften müssen mit
n2n\\persistence\\orm\\annotation\\AnnoEmbedded
Gehen wir davon aus, dass wir eine Entity
Order
$forename
$surname
Address
Order
Address
Address
app.ini
class Order extends ObjectAdapter {
private static function _annos(AnnoInit $ai) {
$ai->p('address', new AnnoEmbedded(Address::getClass()));
$ai->p('deliveryAddress', new AnnoEmbedded(Address::getClass(), 'delivery_'));
}
private $id;
private $productName;
private $address;
private $deliveryAddress;
public function getProductName() {
return $this->productName;
}
public function setProductName($productName) {
$this->productName = $productName;
}
/**
* @return Address
*/
public function getAddress() {
return $this->address;
}
public function setAddress(Address $address) {
$this->address = $address;
}
public function hasDeliveryAddress() {
return $this->deliveryAddress !== null;
}
/**
* @return Address
*/
public function getDeliveryAddress() {
return $this->deliveryAddress;
}
public function setDeliveryAddress(Address $deliveryAddress = null) {
$this->deliveryAddress = $deliveryAddress;
}
}
Damit die Eigenschaften der Extraklasse
Address
AnnoEmbedded
Hinweis: Der angegebene Prefix und Suffix wird bei Beziehungs-Eigenschaften auch für die Namen der Join-Spalten und Zwischentabellen verwendet.
AnnoEmbedded
ReflectionClass
n2n\\reflection\\ObjectAdapter
class Address extends ObjectAdapter {
private $forename;
private $surname;
// more properties
public function __construct($forename = null, $surname = null) {
$this->forename = $forename;
$this->surname = $surname;
}
public function getForename() {
return $this->forename;
}
public function setForename($forename) {
$this->forename = $forename;
}
public function getSurname() {
return $this->surname;
}
public function setSurname($surname) {
$this->surname = $surname;
}
}
Zur Entity
Order
CREATE TABLE `order` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`product_name` VARCHAR(50) NOT NULL,
`forename` VARCHAR(50) NOT NULL,
`surname` VARCHAR(50) NOT NULL,
`delivery_forename` VARCHAR(50) DEFAULT NULL,
`delivery_surname` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Ist
Order::$deliveryAddress
null
Order::$deliveryAddress
null
In folgendem Beispiel erstellen wir eine Bestellung mit und eine ohne Lieferadresse:
public function doOrm(EntityManager $em) {
$this->beginTransaction();
$order = new Order();
$order->setProductName('Broccoli');
$order->setAddress(new Address('Peter', 'Awesome'));
$order->setDeliveryAddress(new Address('Amanda', 'Pretty'));
$em->persist($order);
$order = new Order();
$order->setProductName('ZSC Playoff Tickets');
$order->setAddress(new Address('Peter', 'Awesome'));
$em->persist($order);
$this->commit();
}
Das oben stehende Beispiel schreibt folgende zwei Zeilen in die Tabelle "order":
| id | product_name | forename | surname | delivery_forename | delivery_surname |
|---|---|---|---|---|---|
| 1 | Broccoli | Peter | Awesome | Amanda | Pretty |
| 2 | ZSC Playoff Tickets | Peter | Awesome | NULL | NULL |
Abfragen
Folgende Beispiele zeigen, wie du "embedded" Eigenschaften in Abfragen verwenden kannst.
Beispiel 1
Criteria API
$criteria = $em->createSimpleCriteria(Order::getClass(), ['address.forename' => 'Peter']);
NQL
$criteria = $em->createNqlCriteria('SELECT o FROM \"Order\" o WHERE o.address.forename = :forename', ['forename' => 'Peter']);
Beispiel 2
Criteria API
$address = new Address('Peter', 'Awesome');
$criteria = $em->createSimpleCriteria(Order::getClass(), ['address' => $address]);
NQL
$address = new Address('Peter', 'Awesome');
$criteria = $em->createNqlCriteria('SELECT o FROM \"Order\" o WHERE o.address = :address', ['address' => $address]);
Beispiel 3
Criteria API
$criteria = $em->createSimpleCriteria(Order::getClass(), ['deliveryAddress' => null]);
NQL
$criteria = $em->createNqlCriteria('SELECT o FROM \"Order\" o WHERE o.deliveryAddress = :deliveryAddress', ['deliveryAddress' => null]);
Attribute Overrides
Über die Annotation
n2n\\persistence\\orm\\annotation\\AnnoAttributeOverrides
AnnoAttributeOverrides
n2n\\persistence\\orm\\annotation\\AnnoColumn
AnnoAttributeOverrides
class News extends Teaser {
private static function _annos(AnnoInit $ai) {
$ai->c(new AnnoAttributeOverrides([
'id' => 'news_id',
'title' => 'news_title',
'description' => 'news_description',
'text' => 'news_text'
]));
}
private $id;
private $text;
// getters / setters
}
In diesem Beispiel haben wir das Beispiel aus dem Abschnitt Mapped Supperclass angepasst und über
AnnoAttributeOverrides
News
Teaser
Die Tabelle von
News
CREATE TABLE `news` (
`news_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`news_title` VARCHAR(50),
`news_description` VARCHAR(255),
`news_text` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Du kannst
AnnoAttributeOverrides
class Order extends ObjectAdapter {
private static function _annos(AnnoInit $ai) {
$ai->p('address', new AnnoEmbedded(Address::getClass()), new AnnoAttributeOverrides([
'forename' => 'bill_forename',
'surname' => 'bill_surname'
]));
$ai->p('deliveryAddress', new AnnoEmbedded(Address::getClass(), 'delivery_'));
}
private $id;
private $productName;
private $address;
private $deliveryAddress;
// getter / setter
}
Hier haben wir das Beispiel aus dem Abschnitt Embedded angepasst und über
AnnoAttributeOverrides
Address
Die Tabelle von
Order
CREATE TABLE `order` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`product_name` VARCHAR(50) NOT NULL,
`bill_forename` VARCHAR(50) NOT NULL,
`bill_surname` VARCHAR(50) NOT NULL,
`delivery_forename` VARCHAR(50) DEFAULT NULL,
`delivery_surname` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;