Hier ist ein einfaches Beispiel. Einem Kontakt sind eine bis viele Telefonnummern zugeordnet. Wenn ein Kontakt gelöscht wird, möchte ich, dass auch alle zugehörigen Telefonnummern gelöscht werden. Daher verwende ich ON DELETE CASCADE. Die Eins-zu-Viele / Viele-zu-Eins-Beziehung wird durch den Fremdschlüssel in den Telefonnummern implementiert.
CREATE TABLE contacts
(contact_id BIGINT AUTO_INCREMENT NOT NULL,
name VARCHAR(75) NOT NULL,
PRIMARY KEY(contact_id)) ENGINE = InnoDB;
CREATE TABLE phone_numbers
(phone_id BIGINT AUTO_INCREMENT NOT NULL,
phone_number CHAR(10) NOT NULL,
contact_id BIGINT NOT NULL,
PRIMARY KEY(phone_id),
UNIQUE(phone_number)) ENGINE = InnoDB;
ALTER TABLE phone_numbers ADD FOREIGN KEY (contact_id) REFERENCES \
contacts(contact_id) ) ON DELETE CASCADE;
Durch Hinzufügen von "ON DELETE CASCADE" zur Fremdschlüsseleinschränkung werden phone_numbers automatisch gelöscht, wenn der zugehörige Kontakt gelöscht wird.
INSERT INTO table contacts(name) VALUES('Robert Smith');
INSERT INTO table phone_numbers(phone_number, contact_id) VALUES('8963333333', 1);
INSERT INTO table phone_numbers(phone_number, contact_id) VALUES('8964444444', 1);
Wenn nun eine Zeile in der Kontakttabelle gelöscht wird, werden alle zugehörigen phone_numbers-Zeilen automatisch gelöscht.
DELETE TABLE contacts as c WHERE c.id=1; /* delete cascades to phone_numbers */
Um dasselbe in Doctrine zu erreichen und dasselbe Verhalten auf DB-Ebene "ON DELETE CASCADE" zu erhalten, konfigurieren Sie die @ JoinColumn mit der Option onDelete = "CASCADE" .
<?php
namespace Entities;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="contacts")
*/
class Contact
{
/**
* @Id
* @Column(type="integer", name="contact_id")
* @GeneratedValue
*/
protected $id;
/**
* @Column(type="string", length="75", unique="true")
*/
protected $name;
/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact")
*/
protected $phonenumbers;
public function __construct($name=null)
{
$this->phonenumbers = new ArrayCollection();
if (!is_null($name)) {
$this->name = $name;
}
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function addPhonenumber(Phonenumber $p)
{
if (!$this->phonenumbers->contains($p)) {
$this->phonenumbers[] = $p;
$p->setContact($this);
}
}
public function removePhonenumber(Phonenumber $p)
{
$this->phonenumbers->remove($p);
}
}
<?php
namespace Entities;
/**
* @Entity
* @Table(name="phonenumbers")
*/
class Phonenumber
{
/**
* @Id
* @Column(type="integer", name="phone_id")
* @GeneratedValue
*/
protected $id;
/**
* @Column(type="string", length="10", unique="true")
*/
protected $number;
/**
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/
protected $contact;
public function __construct($number=null)
{
if (!is_null($number)) {
$this->number = $number;
}
}
public function setPhonenumber($number)
{
$this->number = $number;
}
public function setContact(Contact $c)
{
$this->contact = $c;
}
}
?>
<?php
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$contact = new Contact("John Doe");
$phone1 = new Phonenumber("8173333333");
$phone2 = new Phonenumber("8174444444");
$em->persist($phone1);
$em->persist($phone2);
$contact->addPhonenumber($phone1);
$contact->addPhonenumber($phone2);
$em->persist($contact);
try {
$em->flush();
} catch(Exception $e) {
$m = $e->getMessage();
echo $m . "<br />\n";
}
Wenn Sie es jetzt tun
# doctrine orm:schema-tool:create --dump-sql
Sie werden sehen, dass dasselbe SQL generiert wird wie im ersten Raw-SQL-Beispiel