我有一些实体类,我想分享一些共同的方面。我有MagazineEntity和PublisherEntity。例如,我希望他们拥有一系列指向其他网站的链接(杂志官方网页,维基百科条目以及引用它的一些新网站,以及发布商的类似链接)。
要存储这些链接,因为它们中的很多都与每个实体相关,我认为我应该使用新的LinkEntity从Magazine创建一个OneToMany关系。但这将使得为PublisherLink创建另一个实体类成为必要,因为第一个LinkEntity将存储来自Magazine的ID,它可以与Publisher ID或Issue ID相同。如果没有,这就是我的意思:
Magazine: [ID: 1]
LinkEntity: [ID: 1, Link: http://MagazineWebsite/, RelatedID: 1]
LinkEntity: [ID: 3, Link: http://MagazineWebsite2/, RelatedID: 1]
LinkEntity: [ID: 4, Link: http://MagazineWebsite3/, RelatedID: 1]
LinkEntity: [ID: 7, Link: http://MagazineWebsite4/, RelatedID: 1]
因此,如果我在发布者中使用相同的LinkEntity,它会存储:
Publisher: [ID: 1]
LinkEntity: [ID: 2, Link: http://PublisherWebsite/, RelatedID: 1]
LinkEntity: [ID: 5, Link: http://PublisherWebsite2/, RelatedID: 1]
LinkEntity: [ID: 6, Link: http://PublisherWebsite3/, RelatedID: 1]
因此,在检索时,我会以所有这些结束,因为它们没有区别,但我只想引用我的实际实体(无论是发布者还是杂志)。那么简单的方法就是添加另一个字段,比如“RelatedType”,它让我解决了我不知道如何从原始的Magazine实体或Publisher实体中检索它的问题。
如何以优化的方式实现这一目标?
答案 0 :(得分:1)
解决此问题的一种方法是使用多个JOIN表,参见Doctrine Association Mapping关于单向一对多映射的第6.6章。
生成的注释可能看起来像这样(请注意,您应该将实体拆分为多个文件,这仅用于说明ORM映射注释):
<?PHP
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="Magazine")
*/
class Magazine
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ManyToMany(targetEntity="Link")
* @JoinTable(name="Magazine_Links",
* joinColumns={
* @JoinColumn(name="Magazine_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="Link_id", referencedColumnName="id", unique=true)}
* )
**/
protected $links;
public function __construct()
{
$this->links = new ArrayCollection();
}
}
/**
* @ORM\Entity
* @ORM\Table(name="Issue")
*/
class Issue
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ManyToMany(targetEntity="Link")
* @JoinTable(name="Issue_Links",
* joinColumns={
* @JoinColumn(name="Issue_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="Link_id", referencedColumnName="id", unique=true)}
* )
**/
protected $links;
/**
* @ManyToOne(targetEntity="Magazine")
* @JoinColumn(name="magazine_id", referencedColumnName="id")
**/
protected $magazine;
public function __construct()
{
$this->links = new ArrayCollection();
}
}
/**
* @ORM\Entity
* @ORM\Table(name="Publisher")
*/
class Publisher
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ManyToMany(targetEntity="Link")
* @JoinTable(name="Publisher_Links",
* joinColumns={
* @JoinColumn(name="Publisher_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @JoinColumn(
* name="Link_id", referencedColumnName="id", unique=true)}
* )
**/
protected $links;
public function __construct()
{
$this->links = new ArrayCollection();
}
}
/**
* @ORM\Entity
* @ORM\Table(name="Link")
*/
class Link
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $uri;
}
?>