我目前正在使用Doctrine2处理Symfony2 / mySQL项目。在我们的构想中,我们有一个超级"由抽象子类扩展的抽象类,它们本身由具体类扩展。
这是我的代码:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Description of SuperAbstractClass
*
* @author gbrugiere
* @ORM\Table(name="superabstractclass")
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string", length=2)
* @ORM\DiscriminatorMap({"AC" = "AbstractClass","C1" = "ConcreteClass1", "C2" = "ConcreteClass2"})
*/
abstract class SuperAbstractClass {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="label", type="text", nullable=false)
*/
protected $label;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set libellé
*
* @param string $label
* @return SuperAbstractClass
*/
public function setLabel($label)
{
$this->label = $label;
return $this;
}
/**
* Get libellé
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
}
?>
然后:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of SuperAbstractClass
*
* @author gbrugiere
* @ORM\Table(name="abstractclass")
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string", length=2)
* @ORM\DiscriminatorMap({"C1" = "ConcreteClass1", "C2" = "ConcreteClass2"})
*/
abstract class AbstractClass extends SuperAbstractClass {
/**
* @var string
*
* @ORM\Column(name="souslibelle", type="text", nullable=false)
*/
protected $sousLibelle;
/**
* Set sous-libellé
*
* @param string $sousLibelle
* @return AbstractClass
*/
public function setSousLibelle($sousLibelle)
{
$this->sousLibelle = $sousLibelle;
return $this;
}
/**
* Get sous-libellé
*
* @return string
*/
public function getSousLibelle()
{
return $this->sousLibelle;
}
}
?>
这是我的最后一段代码:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of ConcreteClass1
*
* @author gbrugiere
* @ORM\Table(name="concreteclass1")
* @ORM\Entity
*/
class ConcreteClass1 extends AbstractClass {
/**
* @var string
*
* @ORM\Column(name="details", type="text", nullable=false)
*/
private $details;
/**
* Set details
*
* @param string $details
* @return ConcreteClass1
*/
public function setDetails($details)
{
$this->details = $details;
return $this;
}
/**
* Get details
*
* @return string
*/
public function getDetails()
{
return $this->details;
}
}
?>
当我生成我的SQL代码时,我得到:
CREATE TABLE superabstractclass (id INT AUTO_INCREMENT NOT NULL, libelle LONGTEXT NOT NULL, discr VARCHAR(2) NOT NULL, PRIMARY KEY(id))
DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE abstractclass (id INT NOT NULL, subLabel LONGTEXT NOT NULL, PRIMARY KEY(id))
DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE concreteclass1 (id INT NOT NULL, details LONGTEXT NOT NULL, PRIMARY KEY(id))
DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE concreteclass2 (id INT NOT NULL, detailsautres LONGTEXT NOT NULL, PRIMARY KEY(id))
DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE abstractclass
ADD CONSTRAINT FK_438A1A85BF396750 FOREIGN KEY (id)
REFERENCES superabstractclass (id) ON DELETE CASCADE;
ALTER TABLE concreteclass1
ADD CONSTRAINT FK_474E75CFBF396750 FOREIGN KEY (id)
REFERENCES superabstractclass (id) ON DELETE CASCADE;
我对最后一行感到有些惊讶。为什么我的concreteclass1
表引用了superabstractclass
(请参阅*FK_474E75CFBF396750*
)而不是abstractclass
。我担心我的数据完整性:如果删除abstractclass
行会发生什么。我仍然会有一个superabstractclass
和一个concreteclass1
行(意思是objet实例),但我会在我的对象上丢失一些信息。
我错过了什么吗?我现在已经找了好几个小时但却找不到任何东西。谢谢你的帮助。
答案 0 :(得分:0)
我建议采用以下设置:
/**
* @ORM\MappedSuperclass
*/
abstract class SuperAbstractClass {...}
和
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractClass extends SuperAbstractClass {...}
和
/**
* @ORM\Table(name="concreteclass1")
* @ORM\Entity
*/
class ConcreteClass1 extends AbstractClass {...}
这将在您的架构中创建一个表(名为concreteclass1),并具有Concrete,Abstract和SuperAbstractClass的所有属性。 您仍然可以使用通用功能(例如,ID生成将起作用)。
如果你有一个额外的ConcreteClass,它将创建一个新的表/实体,然后再次继承你需要的任何东西。
我们也有这样的设置 - 根据我的理解,这里不需要连接继承。