2013-12-13 42 views
3

我正在使用ZF2和Doctrine2構建應用程序。 理念是有一個基本的應用程序實體(讓我們稱之爲UserEntity)。Doctrine 2模塊化應用與實體替換

但是在一個模塊A中,我將擁有另一個UserEntity-like實體,它將用新字段「升級」基本實體。另一個模塊B將添加更多的字段。

例:

BaseUserEntity { 保護的$ id; // ... }

ModuleAUserEntity擴展了BaseUserEntity { protected moduleAId; }

ModuleBUserEntity extends BaseUserEntity { protected moduleBUserName; }

是否有可能以某種方式獲得方法,因此當我調用UserEntity時,它將返回完整的,由模塊升級的實體?例如:

UserEntity { protected $ id; // ... protected moduleAId; protected moduleBUserName; }

是否有另一種方法來實現這樣的事情?是否可以「擴展」一個實體?

回答

0

我有2種不同的方法:

1.首先一個:
你應該看一看: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html

這就是合法的,並通過這樣的方式學說建議。

2.第二個

如果你不想主義惹的數據庫,你可以使用不同的形式給出:

  1. 創建定義的所有類
  2. 的共同行爲的接口
  3. 編寫您的基類,實現該行爲。
  4. 編寫您的子類,實現包含新方法的接口,幷包裝基類的一個實例
  5. 您可以實現在接口中定義的方法,但由於它們已經在父類中實現,你只是繞過對包裝對象的調用。

所以,你正在使用composition over inheritance避免主義(也許你)變得瘋狂

爲了有一個非常乾淨的行爲與教義,我想象中的數據庫是:

  • 與父實體
  • 與孩子實體表的表,包含
    • 與相關父實體的ID的外鍵(這是,在包含asociated這個值父表中的行,因爲孩子必須有家長和孩子域)
    • 所有額外的列

例如:

接口:

namespace DBAL\Entity; 
interface IProfesional 
{ 
    public function setName($name); 
    public function getName(); 
    public function getId(); 
} 

父類:

namespace DBAL\Entity; 
use Doctrine\ORM\Mapping as ORM; 

use DBAL\Entity\User\IUserAware; 

/** 
* Profesional 
* 
* @ORM\Table(name="profesional") 
* @ORM\Entity 
*/ 
class Profesional implements IProfesional 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=45, nullable=true) 
    */ 
    private $name; 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * Set nombre 
    * 
    * @param string $nombre 
    * @return Profesional 
    */ 
    public function setName($nombre) 
    { 
     $this->name = $nombre; 

     return $this; 
    } 

    /** 
    * Get nombre 
    * 
    * @return string 
    */ 
    public function getNombre() 
    { 
     return $this->name; 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

} 

子級:

namespace DBAL\Entity; 
use DBAL\Entity\User\IUserAware; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Jugador 
* 
* @ORM\Table(name="jugador") 
* @ORM\Entity(repositoryClass="DBAL\Repository\JugadorRepository") 
*/ 
class Player implements IProfesional 
{ 


    /** 
    * @var integer 
    * 
    * @ORM\Column(name="profesional_id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    */ 
    private $id; 

    /** 
    * @var \Profesional 
    * 
    * @ORM\OneToOne(targetEntity="Profesional") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="profesional_id", referencedColumnName="id", unique=true) 
    * }) 
    */ 
    private $profesional; 




    /** 
    * Constructor: you create an empty Profesional, 
     so you are sure you will never use a reference to an in-existent object. 
     But anyways, if this is an entity loaded from the database by doctrine, 
     doctrine will fill that field whith an actual professional from the parent table, 
     based in the foreign key id 
    */ 
    public function __construct() 
    { 
      if(!isset($id)){ 
      $this->profesional=new Profesional(); 
     } 
    } 



    /** 
    * Set profesional 
    * 
    * @param \Profesional $profesional 
    * @return Jugador 
     */ 

    public function setProfesional(Profesional $profesional = null) 
    { 
     $this->profesional = $profesional; 

     return $this; 
    } 

    /** 
    * Get profesional 
    * 
    * @return \Profesional 
    */ 
    public function getProfesional() 
    { 
     return $this->profesional; 
    } 

/** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->profesional->getId(); 
    } 



///New fields, for instance: 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="height", type="integer", nullable=true) 
    */ 
    private $height; 

    public function getHeight() 
    { 
     return $this->height; 
    } 
    public function setHeight($h) 
    { 
      $this->height=$h; 
    } 




}