Php inversedBy和mappedBy之间有什么区别?
我正在使用Zend Framework 2和Doctrine 2开发我的应用程序 在编写注释时,我无法理解Php inversedBy和mappedBy之间有什么区别?,php,doctrine-orm,Php,Doctrine Orm,我正在使用Zend Framework 2和Doctrine 2开发我的应用程序 在编写注释时,我无法理解mappedBy和inversedBy之间的区别 我应该在什么时候使用mappedBy 我应该在什么时候使用inversedBy 我什么时候应该两者都不用 以下是一个例子: /** * * @ORM\OneToOne(targetEntity="\custMod\Entity\Person", mappedBy="customer") * @ORM\JoinColumn(name="
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;
我快速搜索了一下,发现了以下内容,但我仍然感到困惑:
- mappedBy必须在(双向)关联的反向侧指定
- 必须在(双向)关联的拥有方指定inversedBy
- ManyToOne始终是双向关联的拥有方
- 一对夫妻总是双向交往的反面
- OneToOne关联的拥有方是表中包含外键的实体
请参见《双向关系》中的,双向关系既有拥有方也有反向方 mappedBy:放入双向关系的反向侧,以引用其所属侧 反向方:放入双向关系的拥有方,以引用其反向方 和 mappedBy与OneToOne、OneToMany或ManyToMany映射声明一起使用的属性 由与OneToOne、ManyToOne或ManyToMany映射声明一起使用的属性反转 注意: 双向关系的拥有方—包含外键的方 在条令文件中有两个关于inversedBy和mappedBy的参考:
,以上的答案不足以让我理解到底发生了什么,因此在深入研究之后,我认为我有一种解释方法,对那些像我一样努力理解的人来说是有意义的 内部条令引擎使用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原则:schema:update--force--dump sql
),您会注意到Category表上没有用于任务的列。(这是因为它没有列注释)
这里需要理解的重要一点是,可变任务仅存在于此,因此内部条令引擎可以使用上面的引用,即其mappedBy类别。现在。。。别在这里像我一样困惑类别不是指类名,而是指任务类上名为“受保护的$Category”的属性
与wise类似,在Tasks类中,$category属性提到它是由=“Tasks”反转的,请注意这是复数,这不是类名的复数,,只是因为该属性在category类中被称为“protected$Tasks”
一旦理解了这一点,就很容易理解inversedBy和mappedBy在做什么,以及在这种情况下如何使用它们
在我的示例中,引用外键(如“tasks”)的一方总是获取inversedBy属性,因为它需要知道该类上的哪个类(通过targetEntity命令)和哪个变量(inversedBy=)可以“向后工作”,并从中获取类别信息。记住这一点的一个简单方法是,将具有foreignkey_id的类是需要具有inversedBy的类
与category一样,category的$tasks属性(不在表中,请记住,仅用于优化目的的类的一部分)由“tasks”映射,这将在两个实体之间正式创建关系,以便条令现在可以安全地使用JOIN SQL语句,而不是两个单独的SELECT语句。如果没有mappedBy,条令引擎将无法从JOIN语句中知道它将在类“Task”中创建什么变量来放置类别信息
希望这能更好地解释它。5.9.1。拥有方和反向方 对于多对多关联,您可以选择哪个实体是所有者,哪个实体是反向方。从开发人员的角度来看,有一个非常简单的语义规则来决定哪一方更适合作为拥有方。您只需问问自己,哪个实体负责连接管理,并选择它作为拥有方 以两个实体(Article和Tag)为例。无论何时,只要您想将一篇文章连接到一个标记,反之亦然,那么主要是这篇文章负责这种关系。无论何时添加新文章,都希望将其与现有或新标记连接。您的createarticle表单可能支持这个概念,并允许直接指定标记。这就是为什么您应该选择文章作为拥有方,因为它使代码更容易理解:
奇怪的是,条令文档编制人员决定省略多对一双向映射的yaml示例,这可能是最常用的@彼得伍斯特,最好的做法是使用注释,因为你在一个地方有关于实体的所有信息!这也适用于多对多关系。对于这些:你可以自己选择多对多协会的拥有方。@AndreasLinden广泛使用并不意味着最佳实践。使用注释动态编写代码不能被认为是最佳实践,它不是php本机的,甚至不是默认情况下包含在所有框架中的。在一个实体中包含有关实体的所有信息