学说 ORM 和继承
Posted
技术标签:
【中文标题】学说 ORM 和继承【英文标题】:Doctrine ORM and inheritance 【发布时间】:2013-08-01 11:39:16 【问题描述】:给定以下实体:
class Entity
protected $id;
class User extends Entity
/** @var Entity */
protected $target;
class Document extends Entity
protected $title;
class Report extends Entity
protected $level;
我需要创建什么映射才能正确映射User
实体。
这里的问题是,我希望能够让User::$target
使用任何实体(因此是Entity
类型提示),并且稍后在代码中能够做出相应的响应,具体取决于它是Document
还是Report
.
这也意味着,在代码中,我需要能够获取 Entity::$title
(如果是 Document
)或 Entity::$level
(如果是 Report
)。
我可以通过教义实现这一点吗?
【问题讨论】:
【参考方案1】:这应该可以正常工作。我没有添加像 "@ORM\Entity" (http://docs.doctrine-project.org/en/latest/reference/annotations-reference.html) 这样的默认注释。 我希望这是您正在寻找的,否则请告诉我。
/**
* @ORM\InheritanceType("SINGLE_TABLE")
*/
class Entity
protected $id;
class User extends Entity
/**
* @ORM\ManyToOne(targetEntity="Entity")
* @var Entity
*/
protected $target;
看看:http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html 由于性能问题,您应该使用单继承而不是类表继承。
否则 Doctrine 将在实体表的子表上进行连接,因为 Doctrine 不知道“实体”具有哪种类型。比如:
SELECT t1.id, t2.title, t3.level FROM entity t1 LEFT JOIN document t2 ON t2.id = t1.id LEFT JOIN report t3 ON t3.id = t1.id
更多的子表将导致更多的连接 -> 慢。
这是您检查目标是文档还是报告并确定您必须访问哪个字段的方式。
// loads all users
$users = $this->em->getRepository('User')->findAll();
foreach($users as $user)
$target = $user->getTarget()
if($target instanceof Document)
echo $target->getTitle();
else if($target instanceof Report)
echo $target->getLevel()
【讨论】:
以上是关于学说 ORM 和继承的主要内容,如果未能解决你的问题,请参考以下文章