Association Mapping(关联映射)
在这一块仔细提一提symfony中Doctrine2常见的关联映射,在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