如何使用主义协会/关系

编辑该页面

如何使用主义协会/关系< /h1>

截屏视频

你喜欢视频教程?检查<一个href="https://symfonycasts.com/screencast/doctrine-relations" class="reference external" rel="external noopener noreferrer" target="_blank">掌握原则的关系视频系列。

两个主要的关系/关联类型:

ManyToOne/对多
最常见的关系,映射在数据库外键列(例如category_id添加列在产品表)。这是只一个从两种不同的关联类型,但看到的关系。
使用一个连接表时,需要双方的关系可以有许多的另一边。“学生”和“类”:每个学生在许多类,每个类都有许多学生)。

首先,你需要确定使用哪个关系。如果双方的关系将包含许多(如另一边。“学生”和“类”),你需要一个关系。否则,你可能需要一个ManyToOne

提示

还有一个OneToOne关系(例如,一个用户有一个概要文件,反之亦然)。在实践中,使用这个类似ManyToOne

将ManyToOne映射关系< /h2>

在这个例子中,每个类别可以联系在一起许多产品。但是,每个产品只能联系在一起一个类别。这种关系可以概括为:许多产品一个类别(或等价,一个类别许多产品)。

从的角度产品实体,这是一个多对一的关系。从的角度类别实体,这是一对多的关系。

地图,首先创建一个类别财产的产品类的ManyToOne注释。你可以用手或用:实体命令,它会问你几个问题关于你们的关系。如果你不确定的答案,别担心!你可以更改设置后:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34
美元php bin /控制台:实体类名的实体来创建或更新(例如BraveChef): >产品新属性名称(按<返回>停止添加字段):>类别字段类型(输入?查看所有类型)[string]: >关系这个实体应该与哪个班?:>类别关系类型吗?[ManyToOne、对多,OneToOne]: > ManyToOne产品。分类属性允许null(可以为空)?(yes / no)[是]:>任何你想添加一个新属性类别,这样您就可以访问/更新产品对象——如。美元类别- > getProducts () ?(yes / no)[是]:是的新字段名在类别(产品):>产品你想自动删除孤立应用\ \产品实体对象(orphanRemoval) ?(yes / no)[不]:>没有新的属性名(按<返回>停止添加字段):>(按回车键完成)

这使得更改两个实体。首先,它增加了一个新的类别财产产品实体(和getter和setter方法):

  • 属性
  • YAML
  • XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日
/ / src /实体/ Product.php名称空间应用程序\实体;/ /……产品{/ /……# [ORM \ ManyToOne (targetEntity:类别::类,inversedBy:“产品”))私人美元类别;公共函数getCategory():哦?类别{返回美元- >类别;}公共函数setCategory(?类别美元类别):自我{美元- >类别=美元类别;返回美元;}}

ManyToOne映射是必需的。它告诉原则使用category_id添加列在产品表与该表中的每条记录的记录类别表。

接下来,自一个类别对象将与许多产品对象时,:实体命令增加了一个产品财产类别类,将这些对象:

  • 属性
  • YAML
  • XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29
/ / src /实体/ Category.php名称空间应用程序\实体;/ /……使用学说\常见的\集合\ArrayCollection;使用学说\常见的\集合\集合;类别{/ /……# [ORM \ OneToMany (targetEntity:产品::类的mappedBy:“类别”))私人美元产品;公共函数__construct(){美元- >产品=ArrayCollection ();}/ * * *@return收藏|产品[]* /公共函数getProducts():集合{返回美元- >产品;}/ / addProduct()和removeProduct()也补充道}

ManyToOne之前显示的映射要求但是,这对多是可选的:只有添加吗如果您希望能够访问相关的产品类别(这是一个问题:实体问你)。在这个例子中,它是有用的能够调用$分类- > getProducts ()。如果你不想要,那么你也不需要inversedBy的mappedBy配置。

里面的代码__construct ()重要的是:美元的产品属性必须集合对象实现原则集合接口。在这种情况下,一个<一个href="https://www.doctrine-project.org/projects/doctrine-collections/en/1.6/index.html" class="reference external" rel="external noopener noreferrer" target="_blank">ArrayCollection使用对象。这看起来几乎和行为完全像一个数组,但有一些增加了灵活性。想象一下,这是一个数组你会处于良好状态。

数据库设置!现在,运行迁移像正常:

1 2
美元php bin /控制台学说:迁移:diff美元php bin /控制台学说:迁移:迁移

多亏了关系,这将创建一个category_id添加外键列上产品表。原则是可以坚持我们的关系了!

从反方面设置信息< /h2>

到目前为止,您已经更新通过调用的关系(产品- > setCategory美元类别)。这绝非偶然!每个关系都有两个方面:在这个例子中,Product.category拥有一边,Category.products的一面。

在数据库中,你们更新关系必须设置上的关系拥有的一面。拥有一方总是在那里ManyToOne设置(对于一个映射关系,你可以选择哪一方是拥有的一面)。

这意味着它是不可能打电话给吗$分类- > addProduct ()$分类- > removeProduct ()更新数据库?事实上,它可能的,由于一些聪明的代码:实体命令生成:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ / src /实体/ Category.php/ /……类别{/ /……公共函数addProduct(产品美元产品):自我{如果(!美元- >产品- >包含(美元产品)){美元- >产品[]=美元产品;美元产品- >setCategory (美元);}返回美元;}}

关键产品- > setCategory美元(美元),拥有的一面。谢谢,,当你保存,关系更新到数据库中。

是什么删除一个产品从一个类别吗?的:实体命令还生成一个removeProduct ()方法:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/ / src /实体/ Category.php名称空间应用程序\实体;/ /……类别{/ /……公共函数removeProduct(产品美元产品):自我{如果(美元- >产品- >包含(美元产品)){美元- >产品- >removeElement (美元产品);/ /设置拥有一面空(除非已经改变了)如果(美元产品- >getCategory () = = =美元){美元产品- >setCategory ();}}返回美元;}}

谢谢,如果你的电话产品分类- > removeProduct美元(美元),category_id添加在那产品将被设置为在数据库中。

但是,而不是设置category_id添加空,如果你想要什么产品删除如果它变成了“孤儿”(即没有类别)?选择行为,使用<一个href="https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/working-with-associations.html" class="reference external" rel="external noopener noreferrer" target="_blank">orphanRemoval选项里面类别:

  • 属性
1 2 3 4 5 6
/ / src /实体/ Category.php/ /……# [ORM \ OneToMany (targetEntity:产品::类的mappedBy:“类别”,orphanRemoval: true))私人美元产品;

由于这一点,如果产品被删除的类别,它将完全从数据库中删除。

这项工作,包括代码示例,许可下<一个rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons冲锋队3.0许可证。