Những câu trả lời trên không đủ để tôi hiểu chuyện gì đang xảy ra, vì vậy sau khi nghiên cứu kỹ hơn, tôi nghĩ rằng tôi có cách giải thích nó sẽ hợp lý cho những người đang đấu tranh như tôi có thể hiểu được.
inversedBy và mappedBy được sử dụng bởi công cụ INTERNAL DOCTRINE để giảm số lượng truy vấn SQL mà nó phải thực hiện để có được thông tin bạn cần. Để rõ ràng nếu bạn không thêm inversedBy hoặc mappedBy, mã của bạn sẽ vẫn hoạt động nhưng sẽ không được tối ưu hóa .
Ví dụ: hãy xem các lớp bên dưới:
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;
}
Các lớp này nếu bạn chạy lệnh để tạo lược đồ (ví dụ, bin/console doctrine:schema:update --force --dump-sql
) , bạn sẽ nhận thấy rằng bảng Category không có cột trên đó cho các tác vụ. (điều này là do nó không có chú thích cột trên đó)
Điều quan trọng cần hiểu ở đây là các nhiệm vụ biến chỉ ở đó vì vậy công cụ học thuyết nội bộ có thể sử dụng tham chiếu phía trên nó cho biết Danh mục ánh xạ của nó. Bây giờ ... đừng nhầm lẫn ở đây như tôi đã ... Category KHÔNG đề cập đến TÊN LỚP , nó đề cập đến thuộc tính trên lớp Tác vụ được gọi là 'protected $ category'.
Giống như khôn ngoan, trên lớp Nhiệm vụ, thuộc tính $ category đề cập đến nó là inversedBy = "task", lưu ý rằng đây là số nhiều, đây KHÔNG phải là SỐ NHIỀU CỦA TÊN LỚP , mà chỉ vì thuộc tính được gọi là 'protected $ task' trong Danh mục lớp học.
Khi bạn hiểu điều này, bạn sẽ rất dễ hiểu những gì inversedBy và mappedBy đang làm và cách sử dụng chúng trong tình huống này.
Bên tham chiếu đến khóa ngoại như 'task' trong ví dụ của tôi luôn nhận thuộc tính inversedBy vì nó cần biết lớp nào (thông qua lệnh targetEntity) và biến nào (inversedBy =) trên lớp đó để 'hoạt động ngược lại' để nói và nhận thông tin danh mục từ. Một cách dễ dàng để nhớ điều này, là lớp sẽ có ngoại khóa_id là lớp cần phải có inversedBy.
Trong trường hợp với category và thuộc tính $ task của nó (không có trong bảng nhớ, chỉ là một phần của lớp cho mục đích tối ưu hóa) là 'task' của MappedBy, điều này tạo ra mối quan hệ chính thức giữa hai thực thể để học thuyết bây giờ có thể an toàn sử dụng câu lệnh SQL JOIN thay vì hai câu lệnh SELECT riêng biệt. Nếu không có mappedBy, công cụ học thuyết sẽ không biết từ câu lệnh JOIN, nó sẽ tạo ra biến nào trong lớp 'Nhiệm vụ' để đưa thông tin danh mục.
Hy vọng điều này giải thích nó tốt hơn một chút.