Association Mapping(关联映射)

   在这一块仔细提一提symfonyDoctrine2常见的关联映射,在symfony中一般要做关联查询就得先在entity中做关联映射。类似join 语句。

    一般来说,在我们的关联映射中,不外乎下面三种映射。一般来说,阅读映射关联是从左到右,左边的一般为当前Entity,右边是你要做的目标映射,当然做了映射数据表类型应该都是InnoDB\

Many-To-One(多对一)

One-To-Many(一对多)

One-To-One(一对一)

 Many-To-One, Unidirectional(多对一,单向)

    多对一单向的映射,正如它的命名,做了这种映射以后,只会影响你当前Entity,而不会影响你的目标Entity

    这种映射关系一般用于,用户收货地址的关系。一个用户可能会存在多个地址。\

    例如:

<?php

/** @Entity */

class User

{

 // ...

​

 /**

 * Many Users have One Address.

 * @ManyToOne(targetEntity="Address")

 * @JoinColumn(name="address_id", referencedColumnName="id")

 */

 private $address;

}

​

/** @Entity */

class Address

{

 // ...

}

       这里的@JoinColumn是可选的。。如果不写的话,默认会是一个address_id

       Sql模式为:

            \

CREATE TABLE User (

 id INT AUTO_INCREMENT NOT NULL,

 address_id INT DEFAULT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

​

CREATE TABLE Address (

 id INT AUTO_INCREMENT NOT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

​

ALTER TABLE User ADD FOREIGN KEY (address_id) REFERENCES Address(id);

**One-To-One, Unidirectional(一对一单向)**

       一个商品属于一个产品

        \

<?php

​

namespace AppBundle\Entity;

​

use Doctrine\ORM\Mapping as ORM;

​

​

/**

 * Product

 *

 * @ORM\Table(name="product")

 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProductRepository")

 */

class Product

{

 /**

 * One Product has One Shipping.

 * @ORM\OneToOne(targetEntity="AppBundle\Entity\Shipping")

 * @ORM\JoinColumn(name="shipping_id", referencedColumnName="id")

 */

 private $shipping;

}

​

Class Shopping

{

}

     这里的@JoinColumn是可选的。如果不写的话,默认会是一个shopping_id\

    sql是这样的:\

    \

CREATE TABLE Product (

 id INT AUTO_INCREMENT NOT NULL,

 shipping_id INT DEFAULT NULL,

 UNIQUE INDEX UNIQ_6FBC94267FE4B2B (shipping_id),

 PRIMARY KEY(id)

) ENGINE = InnoDB;

CREATE TABLE Shipping (

 id INT AUTO_INCREMENT NOT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

ALTER TABLE Product ADD FOREIGN KEY (shipping_id) REFERENCES Shipping(id);

**One-To-One, Bidirectional(一对一,双向)**\

        一对一双向,代表你的当前Entity以及目标Entity中都必须做映射关系。并且两边都会被影响。

       比如**Customer**和**Cart,用户和车他是属于双向的。用户买了车,车就属于他。**\

use Doctrine\ORM\Mapping as ORM;

​

/**

 * Customer

 *

 * @ORM\Table(name="customer")

 * @ORM\Entity(repositoryClass="AppBundle\Repository\CustomerRepository")

 */

class Customer

{

 // ...

​

 /**

 * One Customer has One Cart.

 * @ORM\OneToOne(targetEntity="AppBundle\Entity\Cart", mappedBy="customer")

 */

 private $cart;

​

 // ...

}

​

class Cart

{

​

 /**

 * One Cart has One Customer.

 * @ORM\OneToOne(targetEntity="AppBundle\Entity\Customer", inversedBy="cart")

 * @ORM\JoinColumn(name="customer_id", referencedColumnName="id")

 */

 private $customer;

​

}

@ORM\JoinColumn可以不用写进来。

CREATE TABLE Cart (

 id INT AUTO_INCREMENT NOT NULL,

 customer_id INT DEFAULT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

CREATE TABLE Customer (

 id INT AUTO_INCREMENT NOT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

ALTER TABLE Cart ADD FOREIGN KEY (customer_id) REFERENCES Customer(id);

把客户的ID加入到Cart,相当于给cart加了一个外键customer_id

One-To-One, Self-referencing(一对一,自身映射)

    假如我们有一个链接的管理。我们可能会是一个无限极分类。每个link可能会有一个父级ID。此时我们查询的时候可能运用到**innerJoin的查询。那么此时我们可能就得在自身去做一个映射关系。

use Doctrine\ORM\Mapping as ORM;

/**

 * Link

 *

 * @ORM\Table(name="link")

 * @ORM\Entity(repositoryClass="AppBundle\Repository\LinkRepository")

 */

class Link

{

 // ...

​

 /**

 * 一个链接有一个父链接

 * @ORM\OneToOne(targetEntity="Link")

 * @ORM\JoinColumn(name="link_id", referencedColumnName="id")

 */

 private $fLink;

​

 // ...

}

@JoinColumn可以不加, 默认值是一样的。

SQL模式:

CREATE TABLE link(

 id INT AUTO_INCREMENT NOT NULL,

 link_id INT DEFAULT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

ALTER TABLE link ADD FOREIGN KEY (link_id) REFERENCES link(id);

相当于把自身的ID给自身加上一个外键。

One-To-Many, Bidirectional(一对多,双向)

如果使用一对多的关联,我们必须是双向影响的。除非你使用一个中间表。

这种双向映射一般都是,当前entity中存在mappedBy属性,OneToMany映射。目标Entity中存在inversedBy属性,和ManyToOne映射

类如,一个标签下可能会存在多篇文章。


use Doctrine\ORM\Mapping as ORM;

use Doctrine\Common\Collections\ArrayCollection;

/**

 * Label

 *

 * @ORM\Table(name="label")

 * @ORM\Entity(repositoryClass="AppBundle\Repository\LabelRepository")

 */

class Label

{

 // ...

 /**

 * 一个标签对应多篇文章

 * @ORM\OneToMany(targetEntity="AppBundle\Entity\Article", mappedBy="label")

 */

 private $label;

 // ...

​

 public function __construct() {

 $this->label = new ArrayCollection();

 }

}

​

/** @Entity */

class Article

{

 // ...

 /**

 * 多个文章有一个标签

 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Label", inversedBy="article")

 * @ORM\JoinColumn(name="label_id", referencedColumnName="id")

 */

 private $article;

 // ...

}

@ORM\JoinColumn(name="label_id", referencedColumnName="id")也是同样可写可不写。


CREATE TABLE Label(

 id INT AUTO_INCREMENT NOT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

CREATE TABLE Article (

 id INT AUTO_INCREMENT NOT NULL,

 article_id INT DEFAULT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

ALTER TABLE Article ADD FOREIGN KEY (label_id) REFERENCES Label(id);

One-To-Many, Unidirectional with Join Table(一堆多,单向链接表)\

在这里看官网给的这块比较模糊,我个人也没用到一对多单向的映射。之后用到了再来做解释。


/**

 * User

 *

 * @ORM\Table(name="User")

 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")

 */

class User

​

​

{

​

​

 //

 ...

​

​

​

​

 /**

​

​

 * @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();

​

​

 }

Many-To-Many, Unidirectional(多对多单向)

一般多对多往往用于单向用户和用户组这样的关系

class User

{

 // ...

​

 /**

 * Many Users have Many Groups.

 * @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;

​

 // ...

​

 public function __construct() {

 $this->groups = new \Doctrine\Common\Collections\ArrayCollection();

 }

}

/* @Entity /


class Group

{

 // ...

}

SQL模式


CREATE TABLE User (

 id INT AUTO_INCREMENT NOT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

CREATE TABLE users_groups (

 user_id INT NOT NULL,

 group_id INT NOT NULL,

 PRIMARY KEY(user_id, group_id)

) ENGINE = InnoDB;

CREATE TABLE Group (

 id INT AUTO_INCREMENT NOT NULL,

 PRIMARY KEY(id)

) ENGINE = InnoDB;

ALTER TABLE users_groups ADD FOREIGN KEY (user_id) REFERENCES User(id);

ALTER TABLE users_groups ADD FOREIGN KEY (group_id) REFERENCES Group(id);

Many-To-Many, Bidirectional(多对多双向)


class User

{

 // ...

​

 /**

 * Many Users have Many Groups.

 * @ManyToMany(targetEntity="Group", inversedBy="users")

 * @JoinTable(name="users_groups")

 */

 private $groups;

​

 public function __construct() {

 $this->groups = new \Doctrine\Common\Collections\ArrayCollection();

 }

​

 // ...

}

/* @Entity /


class Group

{

 // ...

 /**

 * Many Groups have Many Users.

 * @ManyToMany(targetEntity="User", mappedBy="groups")

 */

 private $users;

​

 public function __construct() {

 $this->users = new \Doctrine\Common\Collections\ArrayCollection();

 }

​

 // ...

}

一般来说就是着一些。

另外一般多对多,一对多往往会用到Collections

在你做了映射以后,生成的方法类似就是:


public function __construct() {

 $this->role = new ArrayCollection();

 }

/**

 * Add role

 *

 * @param \Ytdshop\UserBundle\Entity\User $role

 *

 * @return Role

 */

 public function addRole(\Ytdshop\UserBundle\Entity\User $role)

 {

 $this->role[] = $role;

 return $this;

 }

​

 /**

 * Remove role

 *

 * @param \Ytdshop\UserBundle\Entity\User $role

 */

 public function removeRole(\Ytdshop\UserBundle\Entity\User $role)

 {

 $this->role->removeElement($role);

 }

​

 /**

 * Get role

 *

 * @return \Doctrine\Common\Collections\Collection

 */

 public function getRole()

 {

 return $this->role;

 }

那么关于映射的话就这么多,具体映射根据个人需求而定,

这些资料都是我根据Doctrine2官网整理的,希望可以帮到大家。

希望大家尊重下作者,不要直接扒走还不挂我链接。

欢迎大家在下面评论出自己需要的symfony的知识。也可以发邮箱给我。我得邮箱是2798198591@qq.com

讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!