具有实体替换的Doctrine 2模块化应用程序

时间:2013-12-13 18:09:51

标签: entity-framework doctrine-orm zend-framework2

我正在使用ZF2和Doctrine2构建应用程序。 ideia是一个基础app实体(让我们称之为UserEntity)。

但在一个模块A中,我将有另一个类似UserEntity的实体,它将使用新字段“升级”基础实体。另一个模块B将添加更多字段。

例如:

BaseUserEntity {      protected $ id;      // ... }

ModuleAUserEntity扩展BaseUserEntity {     protected moduleAId; }

ModuleBUserEntity扩展BaseUserEntity {     protected moduleBUserName; }

是否有可能以某种方式获得一个方法,所以当我调用UserEntity时,它将返回完整的,逐个模块化的实体?例如:

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

还有另一种方法来实现这样的目标吗?是否可以“扩展”实体?

1 个答案:

答案 0 :(得分:0)

我有两种不同的方法:

1.第一个:
你应该看看: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html

这是合法的,并通过学说的方式推荐这样做。

<强> 2。第二个

如果您不希望教条弄乱数据库,您可以使用不同的方法:

  1. 创建一个定义所有类的常见行为的界面
  2. 编写基类,实现该行为。
  3. 编写子类,实现接口,包含新方法,并包装基类的实例
  4. 您实现了接口中定义的方法,但由于它们已经在父类中实现,因此您只需绕过对包装对象的调用。
  5. 所以,你正在使用composition over inheritance来避免教条(可能还有你)疯狂

    为了使用doctrine有一个非常干净的行为,我想象的数据库是:

    • 包含父实体的表
    • 包含子实体的表
      • 具有相关父实体的id的外键(这是父表中包含与此相关的值的行,因为子项必须包含父字段和子字段)
      • 所有额外的列

    例如:

    接口:

    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;
        }
    
    
    
    
    }