我需要将一些不可变字段移到单独的类中,但我真的不想使用“join”,因为我每次都需要将所有数据放在一起。
有什么方法可以将一些实体属性作为映射到同一个表的类吗?
类似:
/**
* @ORM\Entity
*/
class User {
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* @var Address
* @ORM\... ??
*/
protected $address
}
/**
* @ORM\ValueObject ??
*/
class Address {
/**
* @var string
* @ORM\Column(type="string", name="address_zipcode", length=12)
*/
protected $zipcode;
/**
* @var string
* @ORM\Column(type="string", name="address_country_iso", length=3)
*/
protected $countryIso;
...
}
表结构将是:
CREATE TABLE User (
`id` INT(11) NOT NULL auto_increment,
`address_zipcode` VARCHAR(12) NOT NULL,
`address_country_iso` VARCHAR(3) NOT NULL,
PRIMARY KEY (`id`)
);
您所问的称为值对象。
Jira DDC-93 中有一个未解决的问题,需要添加支持。目前,该问题在 2.5 版中被标记为“已解决”,该版本刚刚在 Beta 版中发布。
如果您想在没有连接的情况下存储对象:
/**
* @ORM\Column(name="adress", type="object")
*/
它将自动序列化/反序列化到文本字段
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html
并添加您想要存储的类型的设置器
public function setAdress(Address $adress)
{
$this->adress = $adress;
return $this;
}
Adress 类不需要任何 @ORM 注释
就像你说的那样。
将@PreUpdate和@PostLoad钩子添加到
User
。
/**
* @ORM\Entity
*/
class User {
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* @var Address
* (NOTE: no @ORM annotation here)
*/
protected $address
/**
* @var string
* @ORM\Column(type="string")
*/
protected $addressZipCode;
/**
* @var string
* @ORM\Column(type="string")
*/
protected $addressCountryIso;
public function setAddress(Address $address)
{
$this->address = $address;
}
/**
* @ORM\PreUpdate
*
* set $addressZipCode and $addressCountryInfo when this object is to
* save so that doctrine can easily save these scalar values
*/
public function extractAddress()
{
$this->addressZipCode = $this->address->getZipCode();
$this->addressCountryIso = $this->address->getAddressCountryIso();
}
/**
* @ORM\PostLoad
*
* When the row is hydrated into this class,
* $address is not set because that isn't mapped.
* so simply, map it manually
*/
public function packAddress()
{
$this->address = new Address();
$this->address->setZipCode($this->addressZipCode);
$this->address->setCountryIs($this->addressCountryIso);
}
}
Doctrine 在版本
2.x
中引入了值对象的概念。
新属性/注释的名称为
Embeddable
和 Embedded
。第一个用于标记值对象类,第二个用于将值对象实际注入到父实体中。
这是我原来问题的更新代码片段:
/** @ORM\Entity */
class User {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/** @ORM\Embedded(class="Address", columnPrefix="address") */
protected $address
}
/** @ORM\Embeddable */
class Address {
/** @ORM\Column(type="string", name="address_zipcode", length=12) */
protected $zipcode;
/** @ORM\Column(type="string", name="address_country_iso", length=3) */
protected $countryIso;
...
}
资源: