program tip

inversedBy와 mappingBy의 차이점은 무엇입니까?

radiobox 2020. 8. 23. 08:53
반응형

inversedBy와 mappingBy의 차이점은 무엇입니까?


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;

빠른 검색을했고 다음을 찾았지만 여전히 혼란 스럽습니다.


  • (양방향) 연관의 반대쪽mappingBy 를 지정해야합니다.
  • inversedBy(양방향) 연관 소유 측 에서 지정되어야합니다.

교리 문서에서 :

  • ManyToOne은 항상 양방향 연결의 소유 측입니다.
  • OneToMany는 항상 양방향 연결의 반대쪽입니다.
  • OneToOne 할당의 소유 측은 외래 키를 포함하는 테이블이있는 엔티티입니다.

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


위의 답변은 무슨 일이 일어나고 있는지 이해하기에 충분하지 않았기 때문에 더 자세히 살펴보면 이해하려고 애쓰는 사람들에게 이해가 될만한 설명 방법이 있다고 생각합니다.

inversedBy 및 mappingBy는 필요한 정보를 얻기 위해 수행해야하는 SQL 쿼리 수줄이기 위해 INTERNAL DOCTRINE 엔진에서 사용됩니다 . inversedBy 또는 mappingBy를 추가하지 않으면 코드는 계속 작동하지만 최적화 되지는 않습니다 .

예를 들어, 아래 클래스를보십시오.

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)

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'.

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.

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

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.

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.

Hope this explains it a bit better.


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

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

AND

mappedBy attribute used with the OneToOne, OneToMany, or ManyToMany mapping declaration.

inversedBy attribute used with the OneToOne, ManyToOne, or ManyToMany mapping declaration.

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


5.9.1. Owning and Inverse Side

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

참고URL : https://stackoverflow.com/questions/12493865/what-is-the-difference-between-inversedby-and-mappedby

반응형