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 할당의 소유 측은 외래 키를 포함하는 테이블이있는 엔티티입니다.
답변
위의 답변은 무슨 일이 일어나고 있는지 이해하기에 충분하지 않았기 때문에 더 자세히 살펴보면 내가 이해했던 것처럼 어려움을 겪은 사람들에게 이해가 될만한 설명 방법이 있다고 생각합니다.
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;
}
이러한 클래스는 명령을 실행하여 스키마 (예 :)를 생성 bin/console doctrine:schema:update --force --dump-sql
하는 경우 Category 테이블에 작업에 대한 열이 없음을 알 수 있습니다. (이것은 열 주석이 없기 때문입니다)
여기서 이해해야 할 중요한 점은 변수 작업이 거기에만 있으므로 내부 교리 엔진이 그 위에있는 mappingBy Category라고하는 참조를 사용할 수 있다는 것입니다. 자 … 여기에서 내가 그랬던 것처럼 혼동 하지 마십시오 … Category는 CLASS NAME을 참조 하지 않으며 ‘protected $ category’라는 Task 클래스의 속성을 참조합니다.
마찬가지로, Tasks 클래스에서 속성 $ category는 그것이 inversedBy = “tasks”라고 언급합니다. 이것은 복수형이라는 것을 알 수 있습니다. 이것은 CLASS NAME의 복수형이 아닙니다. 그러나 속성이 Category에서 ‘protected $ tasks’라고 불리기 때문입니다. 수업.
이것을 이해하면 inversedBy와 mappingBy가하는 일과이 상황에서 어떻게 사용하는지 이해하기가 매우 쉬워집니다.
내 예제에서 ‘tasks’와 같은 외래 키를 참조하는 쪽은 항상 inversedBy 속성을 가져옵니다. 말하고 카테고리 정보를 얻으십시오. 이것을 기억하는 쉬운 방법은 foreignkey_id가있는 클래스가 inversedBy가 필요한 클래스라는 것입니다.
범주 및 해당 $ tasks 속성 (테이블에없는 것은 최적화 목적을위한 클래스의 일부만 기억)이 MappedBy ‘tasks’인 경우, 이것은 두 엔티티 간의 관계를 공식적으로 생성하여 교리가 이제 안전하게 수행 될 수 있도록합니다. 두 개의 개별 SELECT 문 대신 JOIN SQL 문을 사용합니다. mappingBy가 없으면 교리 엔진은 JOIN 문을 통해 ‘Task’클래스에 어떤 변수를 만들어 카테고리 정보를 넣을지 알 수 없습니다.
이것이 조금 더 잘 설명되기를 바랍니다.
답변
양방향 관계에는 소유 측과 반대 측이 모두 있습니다.
mappingBy : 양방향 관계의 반대쪽에 넣어 자신의 쪽을 참조하기 위해
inversedBy : 양방향 관계의 소유 측에 넣습니다. 반대 측을 참조합니다.
과
mappedBy의 속성은 OneToOne, OneToMany, 또는 ManyToMany 매핑 선언으로 사용된다.
inversedBy의 OneToOne, ManyToOne, 또는 ManyToMany 매핑 선언으로 사용되는 속성.
주의 사항 : 외래 키를 포함하는 쪽의 양방향 관계의 소유 쪽.
inversedBy 및 mappingBy에 대한 두 가지 참조가 Doctrine Documentation에 있습니다 :
First Link , Second Link
답변
5.9.1. 소유 및 역측
다 대다 연결의 경우 어떤 엔터티가 소유하고 어떤 엔터티가 반대쪽인지 선택할 수 있습니다. 개발자의 관점에서 어느 쪽이 소유 쪽이 더 적합한 지 결정하는 매우 간단한 의미 규칙이 있습니다. 연결 관리를 담당하는 엔티티가 누구인지 스스로에게 물어보고이를 소유 측으로 선택하기 만하면됩니다.
두 항목 기사 및 태그의 예를 살펴 보겠습니다. 기사를 태그에 연결하거나 그 반대로 연결하려고 할 때마다이 관계를 담당하는 것은 대부분 기사입니다. 새 기사를 추가 할 때마다 기존 또는 새 태그와 연결하려고합니다. 기사 작성 양식은 아마도이 개념을 지원하고 태그를 직접 지정할 수 있습니다. 이것이 코드를 더 이해하기 쉽게 만드는 기사를 소유 측으로 선택해야하는 이유입니다.
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html