Symfony和Doctrine中的HowToMany和OneToMany如何?

时间:2012-07-03 19:38:24

标签: php symfony doctrine doctrine-orm

在解释实体之间关系的创建时,我发现文档很差。所以,我将不得不向我的StackExchangers同事寻求帮助。所以,我正在尝试构建以下案例:

案例1

User属于一个或多个GroupGroup可以有多个PermissionUser也可以有Permission

案例2

TicketCategory,多个Tag和多个Comment

提前致谢!

2 个答案:

答案 0 :(得分:17)

当然可以。首先要明白的是,没有“单向”可以做到这一点。 Doctrine在define the relationship方面提供了很大的灵活性 - 即使多个定义产生完全相同的DDL(这一点很重要,理解 - 一些映射选择只会影响ORM的对象端,而不是模型方面)

这是您的用户/组/权限示例,实际上是所有多对多关联(我排除了所有不相关但必需的代码,如PK列定义)

<?php

namespace Your\Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 */
class User
{
  /**
   * Many-To-Many, Unidirectional
   *
   * @var ArrayCollection $groups
   *
   * @ORM\ManyToMany(targetEntity="Group")
   * @ORM\JoinTable(name="user_has_group",
   *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
   * )
   */
  protected $groups;

  /**
   * Many-To-Many, Unidirectional
   *
   * @var ArrayCollection $permissions
   *
   * @ORM\ManyToMany(targetEntity="Permission")
   * @ORM\JoinTable(name="user_has_permission",
   *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
   * )
   */
  protected $permissions;

  public function __construct()
  {
    $this->groups = new ArrayCollection();
    $this->permissions = new ArrayCollection();
  }
}

/**
 * @ORM\Entity
 */
class Group
{
  /**
   * Many-To-Many, Unidirectional
   *
   * @var ArrayCollection $permissions
   *
   * @ORM\ManyToMany(targetEntity="Permission")
   * @ORM\JoinTable(name="group_has_permission",
   *      joinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
   * )
   */
  protected $permissions;

  public function __construct()
  {
    $this->permissions = new ArrayCollection();
  }
}

/**
 * @ORM\Entity
 */
class Permission {}

如果您对此处发生的事情有疑问,请与我们联系。

现在,到第二个例子

<?php

namespace Your\Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 */
class Ticket
{
  /**
   * Many-To-One, Unidirectional
   *
   * @var Category
   *
   * @ORM\ManyToOne(targetEntity="Category")
   * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
   */
  protected $category;

  /**
   * Many-To-Many, Unidirectional
   *
   * @var ArrayCollection $permissions
   *
   * @ORM\ManyToMany(targetEntity="Tag")
   * @ORM\JoinTable(name="tickt_has_tag",
   *      joinColumns={@ORM\JoinColumn(name="ticket_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
   * )
   */
  protected $tags;

  /**
   * One-To-Many, Bidirectional
   *
   * @var ArrayCollection $comments
   *
   * @ORM\OneToMany(targetEntity="Comment", mappedBy="ticket")
   */
  protected $comments;

  public function __construct()
  {
    $this->tags = new ArrayCollection();
    $this->comments = new ArrayCollection();
  }
}

/**
 * @ORM\Entity
 */
class Comment
{
  /**
   * Many-To-One, Bidirectional
   *
   * @var Ticket $ticket
   *
   * @ORM\ManyToOne(targetEntity="Ticket")
   * @ORM\JoinColumn(name="ticket_id", referencedColumnName="id")
   */
  protected $ticket=null;
}

/**
 * @ORM\Entity
 */
class Tag {}

/**
 * @ORM\Entity
 */
class Category {}

和以前一样,如果你想解释任何一个,请告诉我。

P.S。这些都没有经过实际测试,我只是快速地在我的IDE中将它击败了。可能有一两个错字;)

答案 1 :(得分:4)

试试这个:

Class User {  
 /**
  * @ORM\OneToMany(targetEntity="path\to\group", mappedBy="user", cascade={"persist", "remove"})
  */
  private $group;

UserGroup之间您将拥有一对多的关系。targetEntity是您希望与之建立关系的实体的路径,mappedBy是来自Group实体的变量。 cascade表示User可以添加到Group并从Group中删除

班组{

/**
 * @ORM\ManyToOne(targetEntity="path\to\user, inversedBy="group")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;

这是关系的保留方。targetEntity应该有返回父实体的路径,在这种情况下为UserinversedByUser实体的变量。 JoinColumn只是告诉Doctrine要加入的内容,如果您不自行设置,则会自动完成。