使用继承访问表的关系

时间:2011-07-01 20:54:57

标签: php doctrine-orm

我有一个继承类,如下所示:

Relations

您可以很容易地看到用户,建筑物和酒店都有地址(多个),地址表会将所有者的ID保留在其列中。

  1. 我的逻辑是否正确?
  2. 假设我想获取id为2的用户(或建筑物或酒店)的地址;我必须运行DQL语句(以及如何?)或者我可以在没有DQL的情况下使用find()函数获取它吗?
  3. 如果您举例,我会很高兴,因为Doctrine文档没有多大帮助。

    感谢。

    编辑:用户,建筑物和酒店只是象征性名称,这就是为什么他们可以拥有多个地址,否则建筑物和酒店只会有一个地址。

    编辑2 :我想我无法说清楚,当我谈论类表继承时,我的意思是实体类具有Discriminator列

    /**
     * ...
     *
     * @DiscriminatorColumn(name="classname", type="string")
     * @DiscriminatorMap({"Entities\users" = "Entities\users",
     * "Entities\buildings" = "Entities\buildings"}) ... etc
     */
    

    每个子类都与父(Entity)相关,外键关系为“id”。但当然,学说已经为我创造了这种关系。

3 个答案:

答案 0 :(得分:1)

通常地址是典型的value object。值对象通常与合成值对象的实体一起存储,因此既不是关系也不是类表继承。如果您的域名另有说明(例如,您可以对您的地址执行某些操作,则意义),它们可能是实体,而实体Hotel拥有实体Address(持久存储在:m关系表中)和实体Building也持有Address(在不同的n:m关系表中)。

如果你去价值对象路线,情况会有所不同。您可以使用Building实体以及Hotel实体存储地址(就像使用其他值对象一样,可能是MoneyEmail或{ {1}})。所以你根本不需要关系,只需要几个字段。 Doctrine 2的问题是,它不支持Component mapping。组件映射将用于很好地存储值对象。使用Doctrine 2完成同样的事情,你会实现Password@prePersist这样的处理程序:

@postLoad

由于您需要在不同位置序列化/反序列化class Hotel { private ; /** These fields are persisted */ /** @Column(type=string) */ private $addressStreet; /** @Column(type=string) */ private $addressCity; /** @Column(type=string) */ private $addressZip; /** @Column(type=string) */ private $addressCountry; /** @prePersist */ public function serializeValueObjects() { $this->addressStreet = ->address->getStreet(); $this->addressCity = ->address->getCity(); $this->addressZip = ->address->getZip(); $this->addressCountry = ->address->getCountry(); } public function unserializeValueObjects() { $this->address = new Address(->addressStreet, ->addressCity, ->addressZip, ->addressCountry); } } 值对象,您可能希望将序列化代码提取到一个单独的类中。

答案 1 :(得分:1)

/**
 *
 * @Entity
 * @Table(name="proposaltemplate")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="entitytype", type="string")
 * @DiscriminatorMap({"proposal" = "ProposalTemplate","page" = "PageTemplate"})
 *
 */

abstract class AbstractProposalTemplate
{
    /**
     *
     * @var integer
     * @Id
     * @Column(type="integer")
     * @generatedValue(strategy="AUTO")
     *
     */
    private  $id;
}

next

@Entity 

class ProposalTemplate extends AbstractProposalTemplate
{

      @Id
      @Column(type="integer")
      @generatedValue(strategy="AUTO")


    private  $id;

}
next another class

  @Entity

class PageTemplate extends AbstractProposalTemplate
{
   /**
     *
     * @var integer
     * @Id
     * @Column(type="integer")
     * @generatedValue(strategy="AUTO")
     *
     */
    private  $id;
}

答案 2 :(得分:0)

所以你有一个名为“Entity”的超类,它有子类“User”,“Building”和“Hotel”。

您的“实体”实体应与地址具有OneToMany关系。让我们假设它在您的实体定义中看起来像这样:

/**
 * @OneToMany(targetEntity="Address", mappedBy="whose"
 */
protected $addresses;

这是一种或多或少的好方法,尽管使用继承有点臭。

然后,如果您想从地址,用户,建筑物或酒店内迭代地址:

foreach($this->addresses as $address){
    //do something with adderess
}

这会回答你的问题吗?