php inversedBy 和mappedBy 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12493865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:40:16  来源:igfitidea点击:

What is the difference between inversedBy and mappedBy?

phpdoctrine-orm

提问by Developer

I am developing my application using Zend Framework 2 and Doctrine 2.

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

While writting annotations, I am unable to understand the difference between mappedByand inversedBy.

虽然书面方式说明,我无法理解之间的差异mappedByinversedBy

When should I use mappedBy?

我应该什么时候使用mappedBy

When should I use inversedBy?

我应该什么时候使用inversedBy

When should I use neither?

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

Here is an example:

下面是一个例子:

 /**
 *
 * @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;

I did a quick search and found the following, but I am still confused:

我进行了快速搜索并找到了以下内容,但我仍然感到困惑:

回答by Andreas Linden

  • mappedByhas to be specified on the inversed sideof a (bidirectional) association
  • inversedByhas to be specified on the owning sideof a (bidirectional) association
  • 必须在(双向)关联的反面指定mappedBy
  • inversedBy必须在(双向)关联的拥有方指定

from doctrine documentation:

来自教义文件:

  • ManyToOne is always the owning side of a bidirectional assocation.
  • OneToMany is always the inverse side of a bidirectional assocation.
  • The owning side of a OneToOne assocation is the entity with the table containing the foreign key.
  • ManyToOne 始终是双向关联的拥有方。
  • OneToMany 始终是双向关联的反面。
  • OneToOne 关联的拥有方是包含外键的表的实体。

See https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

回答by Joseph Astrahan

The answers above were not sufficient for me to understand what was going on, so after delving into it more I think I have a way of explaining it that will make sense for people who struggled like I did to understand.

上面的答案不足以让我理解发生了什么,所以在深入研究之后,我想我有一种解释它的方法,这对像我一样努力理解的人来说是有意义的。

inversedBy and mappedBy are used by the INTERNAL DOCTRINEengine to reduce the number of SQL queriesit has to do to get the information you need. To be clear if you don't add inversedBy or mappedBy your code will still work but will not be optimized.

INTERNAL DOCTRINE引擎使用inversedBy 和mappedBy来减少为获取所需信息而必须执行的SQL 查询次数。需要明确的是,如果您不添加 inversedBy 或 mapsBy 您的代码仍然可以工作,但不会被优化

So for example, look at the classes below:

例如,看看下面的类:

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;
}

These classes if you were to run the command to generate the schema (for example, bin/console doctrine:schema:update --force --dump-sql) you will notice that the Category table does not have a column on it for tasks. (this is because it does not have a column annotation on it)

如果您要运行命令来生成模式(例如,bin/console doctrine:schema:update --force --dump-sql)这些类,您会注意到 Category 表上没有用于任务的列。(这是因为它上面没有列注释)

The important thing to understand here is that the variable tasks is only there so the internal doctrine engine can use the reference above it which says its mappedBy Category. Now... don't be confused here like I was... Category is NOT referring TO THE CLASS NAME, its referring to the property on the Task class called 'protected $category'.

这里要理解的重要一点是,变量任务只是在那里,所以内部原则引擎可以使用它上面的引用,它说它的mappedBy Category。现在...不要像我一样在这里混淆... Category 不是指类 NAME,它指的是 Task 类上名为“protected $category”的属性。

Like wise, on the Tasks class the property $category mentions it is inversedBy="tasks", notice this is plural, this is NOT THE PLURAL OF THE CLASS NAME, but just because the property is called 'protected $tasks' in the Category class.

同样,在 Tasks 类中,属性 $category 提到它是 inversedBy="tasks",注意这是复数,这不是 CLASS NAME 的复数,只是因为该属性在类别中称为“受保护的 $tasks”班级。

Once you understand this it becomes very easy to understand what inversedBy and mappedBy are doing and how to use them in this situation.

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

The side that is referencing the foreign key like 'tasks' in my example always gets the inversedBy attribute because it needs to know what class (via the targetEntity command) and what variable (inversedBy=) on that class to 'work backwards' so to speak and get the category information from. An easy way to remember this, is the class that would have the foreignkey_id is the one that needs to have inversedBy.

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

Where as with category, and its $tasks property (which is not on the table remember, just only part of the class for optimization purposes) is MappedBy 'tasks', this creates the relationship officially between the two entities so that doctrine can now safely use JOIN SQL statements instead of two separate SELECT statements. Without mappedBy, the doctrine engine would not know from the JOIN statement it will create what variable in the class 'Task' to put the category information.

与类别一样,它的 $tasks 属性(记住它不在表上,只是为了优化目的只是类的一部分)是 MappedBy 'tasks',这在两个实体之间建立了正式的关系,这样学说现在可以安全地使用 JOIN SQL 语句而不是两个单独的 SELECT 语句。如果没有mappedBy,原则引擎不会从JOIN 语句中知道它将在类“Task”中创建什么变量来放置类别信息。

Hope this explains it a bit better.

希望这能更好地解释它。

回答by ahmed hamdy

In bidirectional relationship has both an owning side and an inverse side

在双向关系中,既有拥有方,也有相反方

mappedBy: put into The inverse side of a bidirectional relationship To refer to its owning side

mappingBy: put into 双向关系的反面 引用它的拥有面

inversedBy: put into The owning side of a bidirectional relationship To refer to its inverse side

inversedBy: 放入双向关系的拥有方 引用其逆方

AND

mappedByattribute used with the OneToOne, OneToMany, or ManyToMany mapping declaration.

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

inversedByattribute used with the OneToOne, ManyToOne, or ManyToMany mapping declaration.

inversedBy与OneToOne,多对一,或多对多映射声明使用的属性。

Notice: The owning side of a bidirectional relationship the side that contains the foreign key.

注意:双向关系的拥有方是包含外键的一方。

there two reference about inversedBy and mappedBy into Doctrine Documentation : First Link,Second Link

有两个关于 inversedBy 和mappedBy 到 Doctrine 文档的参考: 第一个链接第二个链接

回答by Micheal Mouner Mikhail Youssif

5.9.1. Owning and Inverse Side

5.9.1. 拥有和反面

For Many-To-Many associations you can chose which entity is the owning and which the inverse side. There is a very simple semantic rule to decide which side is more suitable to be the owning side from a developers perspective. You only have to ask yourself, which entity is responsible for the connection management and pick that as the owning side.

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

Take an example of two entities Article and Tag. Whenever you want to connect an Article to a Tag and vice-versa, it is mostly the Article that is responsible for this relation. Whenever you add a new article, you want to connect it with existing or new tags. Your create Article form will probably support this notion and allow to specify the tags directly. This is why you should pick the Article as owning side, as it makes the code more understandable:

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

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

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