对于您想做的事情,单表继承不是您所需要的。
有 2 个选项:
1)MappedSuperClass(几乎直接来自文档)
你做一个MappedSuperClass
(文档可以在章节中找到6.1: 映射的超类 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#mapped-superclasses),然后在该基类中添加这些公共字段。然后,您可以从基类(映射的超类)扩展需要这些字段的所有类。
/**
* @MappedSuperclass
*/
class MappedSuperclassBase
{
/** @Column(type="datetime") */
protected $creationDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $creationUser;
/** @Column(type="datetime") */
protected $lastChangeDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="updated_by", referencedColumnName="id")
*/
protected $lastChangeUser;
// ... more fields and methods
}
/**
* @Entity
*/
class EntitySubClass extends MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private $id;
// ... more fields and methods
}
2)你使用一个特质
您创建一个特征(或每个字段/关联的几个单独的特征),在需要具有这些公共字段的所有类中使用。
trait BaseTrait
{
/** @Column(type="datetime") */
protected $creationDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="created_by", referencedColumnName="id")
*/
protected $creationUser;
/** @Column(type="datetime") */
protected $lastChangeDateTime;
/**
* @ManyToOne(targetEntity="Application\Entity\User")
* @JoinColumn(name="updated_by", referencedColumnName="id")
*/
protected $lastChangeUser ;
// ... more fields and methods
}
/**
* @Entity
*/
class EntitySubClass
{
use BaseTrait;
/** @Id @Column(type="integer") */
private $id;
// ... more fields and methods
}
对您问题的答复:
a)在文档中您可以阅读:
单表继承是一种继承映射策略,其中层次结构的所有类都映射到单个数据库表。为了区分哪一行代表层次结构中的哪种类型,使用所谓的鉴别器列。
这意味着所有这些实体将共享一个公共表,这绝对不是您想要的。它可能会变成一个巨大的表(每个实体一行),从而减慢查询速度。除此之外,表中还会有以下列:所有不常见的共享字段这些列将为空(null
) 对于没有这些字段的实体。这也意味着那些不共享的字段不能有null
约束。再次直接来自文档:
为了使单表继承在使用旧数据库模式或自行编写的数据库模式的情况下工作,您必须确保所有列不在根实体中,而是在任何不同的子实体中必须允许空值。具有 NOT NULL 约束的列必须位于单表继承层次结构的根实体上。
这种继承仅对于类似于很大范围的实体是必要的,并且不适合您在问题中讨论的示例。
b)您可以只添加基本实体(因此MappedSuperClass
)在一个常见的模型中(比如你的Application
文件夹)。