上面的答案不足以让我了解正在发生的事情,因此在深入研究之后,我认为我有一种解释的方式,这对那些像我一样难以理解的人来说是有意义的。
内部DOCTRINE引擎使用inversedBy和maptedBy 来减少为获取所需信息而必须执行的SQL查询数量。要明确的是,如果您不添加inversedBy或mapdBy,您的代码仍然可以使用,但不会进行优化。
因此,例如,看下面的类:
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类别。现在...不要像我以前那样在这里感到困惑... 类别不是指班级名称,它是指Task类上称为“ protected $ category”的属性。
同样,在Tasks类上,属性$ category提到它是inversedBy =“ tasks”,请注意这是复数形式,这不是类名的复数只是因为该属性在Category中被称为“ protected $ tasks”类。
一旦了解了这一点,就很容易了解inversedB和int的作用,以及在这种情况下如何使用它们。
在我的示例中,引用诸如“任务”之类的外键的那一侧始终具有inversedBy属性,因为它需要知道该类上的哪个类(通过targetEntity命令)和哪个变量(inversedBy =)才能“向后工作”,以便说话并从中获取类别信息。记住这一点的一种简单方法是,将具有Foreignkey_id的类是需要具有inversedBy的类。
与类别相同,其$ tasks属性(不在表中记住,仅为了优化目的,仅是类的一部分)是MappedBy'tasks',这正式在两个实体之间创建了关系,因此该学说现在可以安全地使用使用JOIN SQL语句而不是两个单独的SELECT语句。如果没有mappingBy,则理论引擎将无法从JOIN语句中得知它将在“任务”类中创建什么变量来放置类别信息。
希望这能更好地解释它。