我在弄清楚如何使用Doctrine2配置我的类的映射时遇到了问题。
我想说这些表:
Address table
---------------------
- id
- civic_no
- road
- state
- country
PersonnalAddress table
---------------------
- id
- base_address_id
- type
- is_primary
BusinessAddress table
---------------------
- id
- base_address_id
- business_name
- shipping_phone
- is_primary
并且使用PHP对象:
class Address{}
class BusinessAddress extends Address{}
class PersonalAddress extends Address{}
考虑以下要求:
为了更好地说明问题,我希望数据库中的数据看起来像:
Address table:
id | civic_no | road | state | country
1 123 test qc ca
PersonnalAddress table:
id | base_address_id | type | is_primary
1 1 A 0
2 1 B 1
BusinessAddress table:
id | base_address_id | business_name | shipping_phone | is_primary
1 1 chic choc 1231234 1
实施符合这些要求的解决方案的最佳策略是什么?
答案 0 :(得分:1)
好的,这有点长,但我认为它涵盖了你的所有基础,如果你有任何问题,那么随时可以问。
这有一个警告,我不知道你是否可以在MappedSuperclass上做Many-To-One
。如果这不可能,那么您可以使用类表继承。试试看它是否有效。
请记住,我很快推出了这个代码,它未经测试,因此它可能不正确,但希望您能够了解它是如何工作的。
我们走了!
接口使得更容易说“什么是地址”而不制作抽象类然后重写方法并导致“糟糕的设计”感觉;)
interface Address {
function getCivicNo();
function getRoad();
function getState();
function getCountry();
}
抽象您不需要的实体,但如果您不使用它,则需要复制ID代码。
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractEntity {
/**
* Entity ID column.
*
* @var integer
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
private $id;
public function getId() {
return $id;
}
}
您可以单独存储或链接到“ComplexAddress”
的BasicAddress/**
* @ORM\Entity
*/
class BasicAddress extends AbstractEntity implements Address {
/** @ORM\Column() */
private $road;
public function getRoad() {
return $this->road;
}
// etc etc
}
“ComplexAddress”就是让您重复使用代码将呼叫委托给基本地址。
/**
* @ORM\MappedSuperclass
*/
abstract class ComplexAddress extends AbstractEntity implements Address {
/** @ORM\Many-To-One(targetEntity="BasicAddress")
private $basicAddress;
public function __construct(BasicAddress $basicAddress) {
$this->basicAddress = $basicAddress;
}
public function getRoad() {
return $this->basicAddress->getRoad();
}
// other methods for implementing "Address" just delegate to BasicAddress
}
PublicAddress
/**
* @ORM\Entity()
*/
class PersonalAddress extends ComplexAddress {
/** @ORM\Column(type="boolean") */
private $isPrimary;
public function isPrimary() {
return $isPrimary;
}
// other personal address methods here
}
BusinessAddress
/**
* @ORM\Entity()
*/
class BusinessAddress extends ComplexAddress {
/** @ORM\Column() */
private $businessName;
public function getBusinessName() {
return $this->businessName;
}
// other business address methods here
}
编辑:刚注意到我忘了将级联参数删除,你可能需要直接处理 - 当删除BasicAddress
时也会删除使用它的其他地址。
答案 1 :(得分:0)
您必须在地址和 ManyToOne <上创建 OneToMany 关系,而不是扩展地址类。 / strong> PersonalAddress 与 BusinessAddress 之间的关系。像这样:
<?php
// ...
use Doctrine\Common\Collections\ArrayCollection;
// ...
class Address
{
// ...
/**
* @ORM\OneToMany(targetEntity="PersonalAddress", mappedBy="address")
*/
private $personalAddresses;
/**
* @ORM\OneToMany(targetEntity="BusinessAddress", mappedBy="address")
*/
private $businessAddresses;
public function __construct()
{
$this->personalAddresses = new ArrayCollection();
$this->businessAddresses = new ArrayCollection();
}
// ...
}
而且,对于儿童班:
<?php
// ...
// ...
class PersonalAddress
{
// ...
/**
* @ORM\ManyToOne(targetEntity="Address", inversedBy="personalAddresses")
* @ORM\JoinColumn(name="base_address_id", referencedColumnName="id")
*/
private $address;
// ...
}