【Symfony】 Doctrine 关系映射,一对一、一对多、多一对、多对多的关系映射(Association Mapping)
来源:互联网 发布:淘宝靠谱的日本代购店 编辑:程序博客网 时间:2024/05/01 05:53
One-To-One 关系:
单向映射:
我们有一个user 用户entity,和一个idcard身份证号码entity,user和idcard一对一,user用户关联(referenced the) Idcard,通过user可以关联到idcard,而idcard中并不知道对应的是那个user。
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
35
36
37
38
39
40
41
42
43
44
45
46
/*@entity*/
classUser
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private$id;
/**
* @var string
*
* @ORM\Column(name="username", type="string", length=255)
*/
private$username;
/**
* @var IdCard
* @ORM\OneToOne(targetEntity="IdCard")
* @ORM\JoinColumn(name="IdCard",referencedColumnName="id")
*/
private$IdCard;
。。。。
/*@entity IdCard*/
classIdCard
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private$id;
/**
* @var string
*
* @ORM\Column(name="num", type="string", length=255)
*/
private$num;
。。。。
双向关联:
我们想让user和Idcard 双向关联,也就是说不管从user还是idcard,都能知道对方。
這时候需要二步user不但要关联targetEntity 到IdCard,还要告诉Idcard受user控制,我们是在user里面做的对应关系。
在IdCard Entity中定义user自动映射到User Entity
/*@entity user*/
/**
* @var IdCard
* @ORM\OneToOne(targetEntity="IdCard",inversedBy="user")
* @ORM\JoinColumn(name="IdCard",referencedColumnName="id")
*/
private$IdCard;
/*@entity IdCard*/
/**
*@ORM\OneToOne(targetEntity="User", mappedBy="IdCard")
*/
private$user;
One-To-Many 关系对应:
一对多关联必须是双向的,除非你使用一个额外的连接表.。
双向:
例如我们要做二个entity的一对多的关系映射:
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
<?php
useDoctrine\Common\Collections\ArrayCollection;
/** @ORM\Entity **/
classProduct
{
// ...
/**
* @ORM\OneToMany(targetEntity="Feature", mappedBy="product")
**/
private$features;
// ...
publicfunction__construct(){
$this->features=newArrayCollection();
}
}
/** @ORM\Entity **/
classFeature
{
// ...
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="features")
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
**/
private$product;
// ...
}
单向:
使用中间表实现一对多(单向一对多的联系可以通过一个连接表映射。从理论的角度来看,它只是作为一个单向的多对多映射,一个独特的约束在一个一对多的连接列执行基数)
利用中间表来实现单向一对多关系,维护映射关系:
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
<?php
/** @ORM\Entity **/
classUser
{
// ...
/**
* @ORM\ManyToMany(targetEntity="Phonenumber")
* @ORM\JoinTable(name="users_phonenumbers",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="phonenumber_id", referencedColumnName="id", unique=true)}
* )
**/
private$phonenumbers;
publicfunction__construct()
{
$this->phonenumbers=new\Doctrine\Common\Collections\ArrayCollection();
}
// ...
}
/** @ORM\Entity **/
classPhonenumber
{
// ...
}
一个表内的一对多,表内存在父子关系的,比如做分类,也很常用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
/** @ORM\Entity **/
classCategory
{
// ...
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
**/
private$children;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private$parent;
// ...
publicfunction__construct(){
$this->children=new\Doctrine\Common\Collections\ArrayCollection();
}
}
Many-To-One 多对一关系:
多对一是分成常见的一个关系:
单向:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
/** @Entity **/
classUser
{
// ...
/**
* @ManyToOne(targetEntity="Address")
* @JoinColumn(name="address_id", referencedColumnName="id")
**/
private$address;
}
/** @Entity **/
classAddress
{
// ...
}
双向:
如上面的例子,很多用户user的address都和 adddress实体对应,這个时候从用户可以知道用户的address,而address是不知道自己下面对应的用户。如果要address关联用户,那这种关系就是一对多,
一个地址,关系很多用户。其实也就是OneToMany关系。所以可以参考上面的OneToMany。
Many-To-Many 多对多关系:
真正的多对多关联是不常见。
单向:
下面的例子显示了用户和组之间的单向关联实体:
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
<?php
/** @ORM\Entity **/
classUser
{
// ...
/**
* @ORM\ManyToMany(targetEntity="Group")
* @ORM\JoinTable(name="users_groups",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
**/
private$groups;
// ...
publicfunction__construct(){
$this->groups=new\Doctrine\Common\Collections\ArrayCollection();
}
}
/** @ORM\Entity **/
classGroup
{
// ...
}
双向:
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
/** @ORM\Entity **/
classUser
{
// ...
/**
* @ORM\ManyToMany(targetEntity="Group", inversedBy="users")
* @ORM\JoinTable(name="users_groups")
**/
private$groups;
publicfunction__construct(){
$this->groups=new\Doctrine\Common\Collections\ArrayCollection();
}
// ...
}
/** @ORM\Entity **/
classGroup
{
// ...
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="groups")
**/
private$users;
publicfunction__construct(){
$this->users=new\Doctrine\Common\Collections\ArrayCollection();
}
// ...
}
因为是多对多,是靠一个中间表来维护射映关系,其实单向和双向并没有什么区别。
tips:
例子中用到很多 ArrayCollection,因为普通的PHP数组会丢失很多的ORM的特性,这些特性使其适用于延迟加载在ORM的上下文中。
ArrayCollection集合类既不是ORM的一部分,也不是DBAL,外面是一个简单的PHP类,没有依赖关系除了依赖于PHP本身(SPL)。
0 0