16

在关联映射的这个页面上,manytomany 部分中有一个示例。但我不明白哪个实体(组或用户)是拥有方。

http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#many-to-many-bidirectional

我也把代码放在这里

<?php
/** @Entity */
class User
{
    // ...

    /**
     * @ManyToMany(targetEntity="Group", inversedBy="users")
     * @JoinTable(name="users_groups")
     */
    private $groups;

    public function __construct() {
        $this->groups = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

/** @Entity */
class Group
{
    // ...
    /**
     * @ManyToMany(targetEntity="User", mappedBy="groups")
     */
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

我是否像这样阅读此注释: User is mappedBy groups so group 是进行连接管理的实体,因此是拥有方?

另外,我在文档中读过这个:

For ManyToMany bidirectional relationships either side may be the owning side (the side  that defines the @JoinTable and/or does not make use of the mappedBy attribute, thus using   a default join table).

这让我认为 User 将是拥有方,因为 JoinTable 注释是在该实体中定义的。

4

2 回答 2

17

但我不明白哪个实体(组或用户)是拥有方

User实体是所有者。您在用户中有组的关系:

/**
 * @ManyToMany(targetEntity="Group", inversedBy="users")
 * @JoinTable(name="users_groups")
 */
private $groups;

看上面,$groupsvar 包含与该用户关联的所有组,但是如果您注意到属性定义,$groupsvar 具有相同mappedByvalue 名称 (mappedBy=" groups"),就像您所做的那样:

/**
 * @ManyToMany(targetEntity="User", mappedBy="groups")
 */
private $users;

是什么意思?

此选项指定作为此关系拥有方的 targetEntity 上的属性名称。

于 2012-11-13T01:07:39.150 回答
16

取自文档:

在一对一关系中,在其自己的数据库表上持有相关实体的外键的实体始终是关系的拥有方。

在多对一关系中,默认情况下多方是拥有方,因为它拥有外键。默认情况下,关系的 OneToMany 端是反向的,因为外键保存在 Many 端。OneToMany 关系只能是拥有方,如果它使用带有连接表的 ManyToMany 关系来实现,并且限制一侧只允许每个数据库约束的唯一值。

现在,我知道 ManyToMany 有时会让人感到困惑。

对于多对多关联,您可以选择哪个实体是拥有者以及哪个实体是反面。从开发人员的角度来看,有一个非常简单的语义规则可以决定哪一方更适合作为拥有方。您只需要问自己,哪个实体负责连接管理,然后选择它作为拥有方。

以文章和标签两个实体为例。每当您想将文章连接到标签时,反之亦然,主要是文章负责这种关系。每当您添加新文章时,您都希望将其与现有或新标签联系起来。您的 createArticle 表单可能会支持此概念并允许直接指定标签。这就是为什么你应该选择文章作为拥有方,因为它使代码更易于理解:

<?php
class Article
{
    private $tags;

    public function addTag(Tag $tag)
    {
        $tag->addArticle($this); // synchronously updating inverse side
        $this->tags[] = $tag;
    }
}

class Tag
{
    private $articles;

    public function addArticle(Article $article)
    {
        $this->articles[] = $article;
    }
}

这允许对在关联的文章侧添加的标签进行分组:

<?php
$article = new Article();
$article->addTag($tagA);
$article->addTag($tagB);

所以,简而言之,任何对你更有意义的东西。你选择关系的拥有和反面。:)

资料来源:http ://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html

于 2012-11-12T16:01:52.680 回答