Symfony2 ManyToMany在不同的类实体中

时间:2014-08-09 14:29:53

标签: php symfony doctrine

我有一些实体类,我想分享一些共同的方面。我有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实体中检索它的问题。

如何以优化的方式实现这一目标?

1 个答案:

答案 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;
}
?>