Php inversedBy和mappedBy之间有什么区别?

Php inversedBy和mappedBy之间有什么区别?,php,doctrine-orm,Php,Doctrine Orm,我正在使用Zend Framework 2和Doctrine 2开发我的应用程序 在编写注释时,我无法理解mappedBy和inversedBy之间的区别 我应该在什么时候使用mappedBy 我应该在什么时候使用inversedBy 我什么时候应该两者都不用 以下是一个例子: /** * * @ORM\OneToOne(targetEntity="\custMod\Entity\Person", mappedBy="customer") * @ORM\JoinColumn(name="

我正在使用Zend Framework 2和Doctrine 2开发我的应用程序

在编写注释时,我无法理解
mappedBy
inversedBy
之间的区别

我应该在什么时候使用
mappedBy

我应该在什么时候使用
inversedBy

我什么时候应该两者都不用

以下是一个例子:

 /**
 *
 * @ORM\OneToOne(targetEntity="\custMod\Entity\Person", mappedBy="customer")
 * @ORM\JoinColumn(name="personID", referencedColumnName="id")
 */
protected $person;

/**
 *
 * @ORM\OneToOne(targetEntity="\Auth\Entity\User")
 * @ORM\JoinColumn(name="userID", referencedColumnName="id")
 */
protected $user;

/**
 *
 * @ORM\ManyToOne (targetEntity="\custMod\Entity\Company", inversedBy="customer")
 * @ORM\JoinColumn (name="companyID", referencedColumnName="id")
 */
protected $company;
我快速搜索了一下,发现了以下内容,但我仍然感到困惑:

      • mappedBy必须在(双向)关联的反向侧指定
      • 必须在(双向)关联的拥有方指定inversedBy
      根据条令文件:

      • ManyToOne始终是双向关联的拥有方
      • 一对夫妻总是双向交往的反面
      • OneToOne关联的拥有方是表中包含外键的实体

      请参见《双向关系》中的,双向关系既有拥有方也有反向方

      mappedBy:放入双向关系的反向侧,以引用其所属侧

      反向方:放入双向关系的拥有方,以引用其反向方

      mappedBy与OneToOne、OneToMany或ManyToMany映射声明一起使用的属性

      由与OneToOne、ManyToOne或ManyToMany映射声明一起使用的属性反转

      注意: 双向关系的拥有方—包含外键的方

      在条令文件中有两个关于inversedBy和mappedBy的参考:

      以上的答案不足以让我理解到底发生了什么,因此在深入研究之后,我认为我有一种解释方法,对那些像我一样努力理解的人来说是有意义的

      内部条令引擎使用inversedBy和mappedBy来减少获取所需信息所需的SQL查询数量。要明确的是,如果不添加inversedBy或mappedBy,您的代码仍然可以工作,但不会进行优化

      例如,看看下面的类:

      class Task
      {
          /**
           * @var int
           *
           * @ORM\Column(name="id", type="integer")
           * @ORM\Id
           * @ORM\GeneratedValue(strategy="AUTO")
           */
          private $id;
      
          /**
           * @var string
           *
           * @ORM\Column(name="task", type="string", length=255)
           */
          private $task;
      
          /**
           * @var \DateTime
           *
           * @ORM\Column(name="dueDate", type="datetime")
           */
          private $dueDate;
      
          /**
           * @ORM\ManyToOne(targetEntity="Category", inversedBy="tasks", cascade={"persist"})
           * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
           */
          protected $category;
      }
      
      class Category
      {
          /**
           * @var int
           *
           * @ORM\Column(name="id", type="integer")
           * @ORM\Id
           * @ORM\GeneratedValue(strategy="AUTO")
           */
          private $id;
      
          /**
           * @var string
           *
           * @ORM\Column(name="name", type="string", length=255)
           */
          private $name;
      
          /**
           * @ORM\OneToMany(targetEntity="Task", mappedBy="category")
           */
          protected $tasks;
      }
      
      这些类如果要运行命令生成模式(例如,
      bin/console原则:schema:update--force--dump sql
      ),您会注意到Category表上没有用于任务的列。(这是因为它没有列注释)

      这里需要理解的重要一点是,可变任务仅存在于此,因此内部条令引擎可以使用上面的引用,即其mappedBy类别。现在。。。别在这里像我一样困惑类别不是指类名,而是指任务类上名为“受保护的$Category”的属性

      与wise类似,在Tasks类中,$category属性提到它是由=“Tasks”反转的,请注意这是复数,这不是类名的复数,,只是因为该属性在category类中被称为“protected$Tasks”

      一旦理解了这一点,就很容易理解inversedBy和mappedBy在做什么,以及在这种情况下如何使用它们

      在我的示例中,引用外键(如“tasks”)的一方总是获取inversedBy属性,因为它需要知道该类上的哪个类(通过targetEntity命令)和哪个变量(inversedBy=)可以“向后工作”,并从中获取类别信息。记住这一点的一个简单方法是,将具有foreignkey_id的类是需要具有inversedBy的类

      与category一样,category的$tasks属性(不在表中,请记住,仅用于优化目的的类的一部分)由“tasks”映射,这将在两个实体之间正式创建关系,以便条令现在可以安全地使用JOIN SQL语句,而不是两个单独的SELECT语句。如果没有mappedBy,条令引擎将无法从JOIN语句中知道它将在类“Task”中创建什么变量来放置类别信息


      希望这能更好地解释它。

      5.9.1。拥有方和反向方

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

      以两个实体(Article和Tag)为例。无论何时,只要您想将一篇文章连接到一个标记,反之亦然,那么主要是这篇文章负责这种关系。无论何时添加新文章,都希望将其与现有或新标记连接。您的createarticle表单可能支持这个概念,并允许直接指定标记。这就是为什么您应该选择文章作为拥有方,因为它使代码更容易理解:


      奇怪的是,条令文档编制人员决定省略多对一双向映射的yaml示例,这可能是最常用的@彼得伍斯特,最好的做法是使用注释,因为你在一个地方有关于实体的所有信息!这也适用于多对多关系。对于这些:你可以自己选择多对多协会的拥有方。@AndreasLinden广泛使用并不意味着最佳实践。使用注释动态编写代码不能被认为是最佳实践,它不是php本机的,甚至不是默认情况下包含在所有框架中的。在一个实体中包含有关实体的所有信息