上面的答案是不足以讓我明白了什麼是在深入研究之後怎麼回事,所以我越覺得我有辦法解釋它對那些像我一樣理解那樣掙扎的人來說是有意義的。
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 doctrine:schema:update --force --dump-sql
),你會發現,在分類表中沒有一個列上的任務。 (這是因爲它沒有列標註)
這裏要理解的重要一點是變量任務只在那裏,所以內部的教條引擎可以使用上面的引用它的mappedBy類的引用。現在...不要在這裏混淆,就像我是... 類別不是指類名稱,它指的是任務類上的屬性,稱爲'保護$類別'。
像明智的,在任務類的屬性$類別提到它是inversedBy =「任務」,請注意這是複數,這是不是類名的複數形式,而是因爲財產被稱爲「保護$任務'在類別類。
一旦你明白了這一點,就很容易理解inversedBy和mappedBy在做什麼以及如何在這種情況下使用它們。
在我的示例中引用外部鍵(如'tasks')的一方總是獲取inversedBy屬性,因爲它需要知道該類的哪個類(通過targetEntity命令)和該類的哪個變量(inversedBy =)工作向後「這樣說,並從中獲取類別信息。一個簡單的方法來記住這個,這個類將有foreignkey_id是需要反轉的那個。
與類別及其$ tasks屬性(不在表格中,記住,僅僅是用於優化目的的類的一部分)屬於MappedBy的「任務」,這會在兩個實體之間正式建立關係,所以教義現在可以安全地使用JOIN SQL語句而不是兩個單獨的SELECT語句。如果沒有mappedBy,則教條引擎不會從JOIN語句中知道它會在類Task中創建什麼變量來放置類別信息。
希望這解釋得更好一點。
奇怪的學說記錄器決定離開了一個多到一個雙向映射的YAML例子,大概最常用的! –
@PeterWooster,最好的做法是使用註釋,因爲你有一個地方的實體的所有信息! –
這也適用於多對多的關係。對於那些人:你可以自己選擇多對多的關聯。 – 11mb