简体   繁体   English

Doctrine Entity扩展另一个实体

[英]Doctrine Entity extending another Entity

Hi I read this article http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html yet I'm not quiet sure how to accomplish the following: 嗨,我读了这篇文章http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html但我不确定如何完成以下内容:

I have a "user"-Table, a "man"-Table and a "woman"-table. 我有一个“用户” - 表,一个“男人” - 表和一个“女人”表。 I want my php classes Man and Woman extend the User Object. 我希望我的php类ManWoman扩展User对象。

Annotationmapping: Annotationmapping:

    namespace Core\Entity;

    use Doctrine\ORM\Mapping as ORM;

    /**
     * User
     *
     * @ORM\Table(name="user", uniqueConstraints={@ORM\UniqueConstraint(name="email_UNIQUE", columns={"email"}), @ORM\UniqueConstraint(name="username_UNIQUE", columns={"username"})})
     * @ORM\Entity
     */
    class User
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer", nullable=false)
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        private $id;

        /**
         * @var string
         *
         * @ORM\Column(name="first_name", type="string", length=255, nullable=true)
         */
        private $firstName;

        /**
         * @var string
         *
         * @ORM\Column(name="middle_name", type="string", length=255, nullable=true)
         */
        private $middleName;

        /**
         * @var string
         *
         * @ORM\Column(name="last_name", type="string", length=255, nullable=true)
         */
        private $lastName;

        /**
         * @var string
         *
         * @ORM\Column(name="username", type="string", length=255, nullable=false)
         */
        private $username;

        /**
         * @var string
         *
         * @ORM\Column(name="email", type="string", length=255, nullable=false)
         */
        private $email;

        /**
         * @var string
         *
         * @ORM\Column(name="password", type="string", length=255, nullable=false)
         */
        private $password;

        /**
         * @var \DateTime
         *
         * @ORM\Column(name="created_at", type="datetime", nullable=true)
         */
        private $createdAt;

        /**
         * @var \DateTime
         *
         * @ORM\Column(name="updated_at", type="datetime", nullable=false)
         */
        private $updatedAt;

        /**
         * @var \DateTime
         *
         * @ORM\Column(name="last_login", type="datetime", nullable=false)
         */
        private $lastLogin;

        /**
         * @var string
         *
         * @ORM\Column(name="login_hash", type="string", length=255, nullable=true)
         */
        private $loginHash;

        /**
         * @var boolean
         *
         * @ORM\Column(name="is_premium", type="boolean", nullable=false)
         */
        private $isPremium = '0';

        /**
         * @var \Doctrine\Common\Collections\Collection
         *
         * @ORM\ManyToMany(targetEntity="Core\Entity\Bill", inversedBy="user")
         * @ORM\JoinTable(name="user_has_bill",
         *   joinColumns={
         *     @ORM\JoinColumn(name="user_id", referencedColumnName="id")
         *   },
         *   inverseJoinColumns={
         *     @ORM\JoinColumn(name="bill_id", referencedColumnName="id")
         *   }
         * )
         */
        private $bill;

        /**
         * @var \Doctrine\Common\Collections\Collection
         *
         * @ORM\ManyToMany(targetEntity="Core\Entity\Picture", inversedBy="user")
         * @ORM\JoinTable(name="user_has_picture",
         *   joinColumns={
         *     @ORM\JoinColumn(name="user_id", referencedColumnName="id")
         *   },
         *   inverseJoinColumns={
         *     @ORM\JoinColumn(name="picture_id", referencedColumnName="id")
         *   }
         * )
         */
        private $picture;

        /**
         * Constructor
         */
        public function __construct()
        {
            $this->bill = new \Doctrine\Common\Collections\ArrayCollection();
            $this->picture = new \Doctrine\Common\Collections\ArrayCollection();
        }

    }

Woman: 女人:

namespace Core\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Woman
 *
 * @ORM\Table(name="woman", indexes={@ORM\Index(name="fk_woman_user1_idx", columns={"user_id"})})
 * @ORM\Entity
 */
class Woman
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $id;

    /**
     * @var \Core\Entity\User
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     * @ORM\OneToOne(targetEntity="Core\Entity\User")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     * })
     */
    private $user;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Core\Entity\Cart", inversedBy="woman")
     * @ORM\JoinTable(name="woman_has_cart",
     *   joinColumns={
     *     @ORM\JoinColumn(name="woman_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="cart_id", referencedColumnName="id")
     *   }
     * )
     */
    private $cart;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Core\Entity\Interest", inversedBy="woman")
     * @ORM\JoinTable(name="woman_has_interest",
     *   joinColumns={
     *     @ORM\JoinColumn(name="woman_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="interest_id", referencedColumnName="id")
     *   }
     * )
     */
    private $interest;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Core\Entity\Man", inversedBy="woman")
     * @ORM\JoinTable(name="woman_has_man",
     *   joinColumns={
     *     @ORM\JoinColumn(name="woman_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="man_id", referencedColumnName="id")
     *   }
     * )
     */
    private $man;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->cart = new \Doctrine\Common\Collections\ArrayCollection();
        $this->interest = new \Doctrine\Common\Collections\ArrayCollection();
        $this->man = new \Doctrine\Common\Collections\ArrayCollection();
    }

}

The man mapping looks (for now) the same as the woman. 男人的映射看起来(现在)和女人一样。

Here a little Snippet from MysqlWorkbench http://s14.directupload.net/images/131013/fbg7okyn.png 这里有一个来自MysqlWorkbench的小片段http://s14.directupload.net/images/131013/fbg7okyn.png

The basic idea is this: 基本的想法是这样的:

Men and Women share some common logic and individual logic. 男人和女人有一些共同的逻辑和个人逻辑。 For example take a login. 例如,登录。 Men and Women need an email and a password to log in. Since it's redundant to implement the same login logic twice I thought of creating a more abstract class, the User , which is where I want to put everything which applies to men and women, like name, email, password, login logic etc... 男人和女人需要一个电子邮件和一个密码才能登录。由于两次实现相同的登录逻辑是多余的,我想创建一个更抽象的类, User ,这是我想把所有适用于男人和女人的东西,如姓名,电子邮件,密码,登录逻辑等...

This is where it gets tricky with doctrine. 这是学说变得棘手的地方。 Men and women will have individual fields to store in the database, yet they still need their "common data"(name, password etc...), so a simple class Man extends User might not work out correctly. 男性和女性将有单独的字段存储在数据库中,但他们仍然需要他们的“通用数据”(名称,密码等...),因此简单的class Man extends User可能无法正常工作。 I store the corresponding id of the User on men and women. 我将User的相应ID存储在男性和女性身上。 So there is an identification. 所以有一个标识。

What I had in mind is, if I do $men->getPassword() it should use the getPassword() function of the corresponding User object. 我的想法是,如果我做$men->getPassword()它应该使用相应User对象的getPassword()函数。

I hope I cleared up my intend. 我希望我清理了我的意图。

Kind Regards and thank you for digging through. 亲切的问候,谢谢你的挖掘。

i have done this what you're looking for in one of my projects once, It's done not too good code wise, but the mapping is fine ;) Please check this link 我已经完成了你在我的一个项目中所寻找的东西,它的代码不是很好,但映射很好;)请检查此链接

  • Item.php.dist would be your User Entity Item.php.dist将是您的用户实体
  • (Property|Vehicle).php.dist would be your Man / Women Entity (财产|车辆).php.dist将是您的男/女实体
  • Please notice that the Property Discriminator Mapping is missing within the code examples. 请注意代码示例中缺少Property Discriminator Mapping。 I do it differently in the application ;) 我在应用程序中做的不同;)

Ultimately you wouldn't want to have separate "Tables" on your SQL Server. 最终,您不希望SQL Server上有单独的“表”。 It all belongs to the Superclass "User" and therefore belongs to the User-Table. 它都属于超类“用户”,因此属于用户表。 You will extends the UserTable and use DiscriminatorMapping to map specific entities. 您将扩展UserTable并使用DiscriminatorMapping映射特定实体。

Note: A Man can not be editted to become a Woman! 注意:男人不能被编辑成为女人! You'd have to kill the man and give birth to a woman :P 你必须杀死这个男人并生下一个女人:P

Imagina this Model: 想象一下这个模型:

User
  *id
  -name
  -surname

Man extends User
  -pc_power

Woman extends User
  -nail_color

Your DB-Schema would look like this: 你的DB-Schema看起来像这样:

Table User:
  *id (pk)
  -discriminator (not nullable) (value: man or woman)
  -name (not nullable)
  -surname (not nullable)
  -pc_power (nullable as far as DB is concerned)
  -nail_color (nullable as far as DB is concerned)

You do not need 3 tables to mod your models like this. 你不需要3个表来修改你的模型。 It makes literally no sense to do this. 这样做完全没有意义。 It just slows your Queries down by quite a bit. 它只会减慢你的查询速度。

Now a Dataset could look like this: 现在数据集看起来像这样:

A Man: (1, man, john, doe, 4ghz, null)
A Woman: (2, woman, john, doe, null, pink)

Now on Doctrines side of things you do Queries against the USER-Entity 现在,在Doctrines方面,您可以对USER-Entity进行查询

$entity = $userRepository->find(1);
echo get_class($entity); // returns "Man"

$entity = $userRepository->find(2);
echo get_class($entity); // returns "Woman"

Does that make things more clear, because otherwise i'm simply unable to help you :P 这会让事情变得更清楚,因为否则我根本无法帮助你:P

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM