下面的脚本来源于https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html#mapped-superclasses,并只改到包括第二子级。这是我的理解是MappedSuperclassBase
不能单独存在,但必须由一个和扩展仅一个子类(即或者EntitySubClassOne
或EntitySubClassTwo
),并且是相同的概念,作为SQL超类型/子类型。同意?
如何超级/子类型使用任一YAML或XML而不是注释映射定义?
<?php
/** @MappedSuperclass */
class MappedSuperclassBase
{
/** @Column(type="integer") */
protected $mapped1;
/** @Column(type="string") */
protected $mapped2;
/**
* @OneToOne(targetEntity="MappedSuperclassRelated1")
* @JoinColumn(name="related1_id", referencedColumnName="id")
*/
protected $mappedRelated1;
// ... more fields and methods
}
/** @Entity */
class EntitySubClassOne extends MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private $id;
/** @Column(type="string") */
private $name;
// ... more fields and methods
}
/** @Entity */
class EntitySubClassTwo extends MappedSuperclassBase
{
/** @Id @Column(type="integer") */
private $id;
/** @Column(type="string") */
private $name;
// ... more fields and methods
}
根据我们的意见,我想我看到你的困惑。由于the docs同时处理“MappedSuperclass”,并在同一页上的“鉴别”,我想你已经在你的脑袋混了它们的用途。希望这可以帮助你:
MappedSuperclass
提供属性/默认值在可重复使用的方法,但这些决不是自身实体。这与PHP的abstract
类(不能对自己被实例化)Person
实体为您提供了1个实体。该实体可以被扩展,例如通过Worker
和Manager
。一个良好的用例的MappedSuperclass
将是一个AbstractEntity
。每一个实体需要一个ID,一个唯一的标识符。它也给你共同之处检查针对听众和这样的。因此,继续创造:
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractEntity
{
/**
* @var int
* @ORM\Id
* @ORM\Column(name="id", type="integer", options={"unsigned":true})
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
// getter / setter
}
怎么看这既是宣告abstract
和MappedSuperclass
?
这是因为无论(abstract class
和MappedSuperclass
)不能对自己被实例化。你不能这样做$entity = new AbstractEntity()
因为它是一个abstract
PHP类。也不会学说创建一个单独的表AbstractEntity
。
接下来,创建一个Person
:
/**
* @ORM\Entity
* @ORM\Table(name="persons")
*
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
*/
class Person extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
protected $name;
// getter / setter
}
以上,Person
,实体是设置用于通过继承Class Table Inheritance类型JOINED
。这意味着,在数据库级别上,表persons
会从其他实体添加任何列,延长Person
分开。
请注意,我怎么没有宣布DiscriminatorMap
。从下面的文档,以粗体强调了我:
需要注意的事项:
- 的@InheritanceType,@DiscriminatorColumn和@DiscriminatorMap必须在是映射的实体层次结构的一部分的最顶层类指定。
- 所述@DiscriminatorMap指定哪些鉴别器字段的值标识的行为是哪种类型的。另外,在上述的“人”的值的情况下标识一行为类型Person和“雇员”的标识一行为Employee类型。
- 在鉴别地图类的名称并不需要,如果类包含在相同的命名空间上应用了鉴别地图实体类是完全合格的。
- 如果没有提供鉴别地图,则地图被自动生成。自动生成的鉴别器映射包含每一类别作为关键的小写短名称。
现在,让我们创建一个Worker
:
/**
* @ORM\Entity
* @ORM\Table(name="workers")
*/
class Worker extends Person
{
/**
* @var int
* @ORM\Column(name="worker_id", type="integer", length=11, nullable=false)
*/
protected $workerId;
// getter / setter
}
所以,现在我们已经有了:
AbstractEntity
- 是不是一个独立的实体Person
- 是一个独立的实体Worker
- 扩展Person
需要注意的事项:
abstract class
$worker instanceof Worker
和$worker instanceof Person
,因为Worker
延伸Person
。然而,$person instanceof Worker
将false
!
$workerId = $person->getWorkerId() // generates "method does not exist" fatal
$workerId = $worker->getWorkerId() // generates integer value
希望设法清除的东西了你。如果没有,随便问。