【问题标题】:Working example of joining two tables with join table using Doctrine 2使用 Doctrine 2 使用连接表连接两个表的工作示例
【发布时间】:2012-10-09 02:52:46
【问题描述】:

Doctrine 有一些很好的文档,但在某些时候,我觉得对于想要进入教义的人来说,要习惯映射的东西是一场小小的战斗。我是属于这个部分的人之一。我已经浏览了大部分映射资料文档,例如 this 和教义官方网站中的其他链接,但对我来说,这些文档看起来像是要遵循的点点滴滴。我这样说是为了我的情况。

是否有一个示例显示如何将两个表与第三个连接表连接起来,我想知道这个模式的基本映射。

假设我有两张桌子:Fruits 和 Country。

关系是一个国家生产多种水果,可以说是一对多的关系。除此之外,我还想使用第三张表进行关联,比如 countryFruits。

Fruits Table
-- fruitsId (PK, AI)
-- fruitName

Country Table
-- countryId (PK, AI)
-- countryName

countryFruits Table
-- fruitsId (PK, FK)
-- countryId (PK, FK)

这就是 MySQL 中的表的外观,并且已经设计好了。现在我可以用教义填充水果表,而在填充国家表时,我遇到了一个混乱的映射问题。

/**
 * @ORM\Entity
 * @ORM\Table(name="fruits")
 * @property string $fruitName
 * @property int $fruitId
 */
class Fruits
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="fruitId", unique=true);
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $fruitId;

    /**
     * @ORM\Column(type="string")
     */
    protected $fruitName;

    /**
     * @ORM\OneToMany(targetEntity="Country", mappedBy="fruits", cascade={"persist"})
     */
    protected $country;

    public function __get($property)
    {
        return $this->$property;
    }

    public function __set($property, $value)
    {
        $this->$property = $value;
    }

}

/**
 * @ORM\Entity
 * @ORM\Table(name="country")
 * @property string $countryName
 * @property int $countryId
 */
class Country
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="countryId", unique=true);
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $countryId;

    /**
     * @ORM\Column(type="string")
     */
    protected $countryName;

    /**
     * @ORM\OneToMany(targetEntity="Fruits", mappedBy="country", cascade={"persist"})
     */
    protected $countries;

    public function __get($property)
    {
        return $this->$property;
    }

    public function __set($property, $value)
    {
        $this->$property = $value;
    }

}

/**     
 * @ORM\Entity
 * @ORM\Table(name="countryFruits ")
 * @property int $fruitId
 * @property int $countryId
 */
class countryFruits
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="fruitId", nullable=false)
     * @ORM\GeneratedValue(strategy="NONE")
     */
    protected $fruitId;

    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="countryId", nullable=false)
     * @ORM\GeneratedValue(strategy="NONE")
     */
    protected $countryId;

    /**
     * @ORM\ManyToOne(targetEntity="Country", inversedBy="fruits", cascade={"persist"})
     * @ORM\JoinColumn(name="countryId", referencedColumnName="countryId")
     */
    protected $country;

    /**
     * @ORM\ManyToOne(targetEntity="Fruits", inversedBy="country", cascade={"persist"})
     * @ORM\JoinColumn(name="fruitId", referencedColumnName="fruitId")
     */
    protected $fruits;

    /**
     * Set fruits
     *
     * @param Fruits $fruits
     */
    public function setFruits($fruits)
    {
        $this->fruits = $fruits;
    }

    /**
     * ´Get fruits
     *
     * @param Fruits $fruits
     */
    public function getFruits()
    {
        return $this->fruits;
    }

    /**
     * Set country
     *
     * @param Country $country
     */
    public function setCountry($country)
    {
        $this->country = $country;
    }

    /**
     * Get country
     *
     * @param Country $country
     */
    public function getCountry($country)
    {
        $this->country = $country;
    }
}

有人可以交叉检查一下,让我知道我的映射是否以正确的方式完成。以防万一,是否有可能获得一小段代码如何将实体持久保存到我的数据库中。

【问题讨论】:

    标签: database doctrine-orm


    【解决方案1】:

    您不需要 countryFruits 类。您正在寻找的是 ManyToMany 关系!您也不想以复数形式命名实体,因为实体始终代表表中的单个对象/行。

    水果实体

    /**
     * @ORM\Entity
     * @ORM\Table(name="fruits")
     * @property string $fruitName
     * @property int $fruitId
     */
    class Fruit
    {
        /**
          * @ORM\ManyToMany(targetEntity="Country")
          * @ORM\JoinTable(name="country_fruits",
          *         joinColumns={@ORM\JoinColumn(name="country_id", referencedColumnName="id")},
          *         inverseJoinColumns={@ORM\JoinColumn(name="fruit_id", referencedColumnName="id")}
          * ) 
          * @var Country[]
          */
          protected $countries;
    }
    

    国家实体

    /**
     * @ORM\Entity
     * @ORM\Table(name="country")
     * @property string $countryName
     * @property int $countryId
     */
    class Country
    {
        /**
          * @ORM\ManyToMany(targetEntity="Fruit")
          * @ORM\JoinTable(name="country_fruits",
          *         joinColumns={@ORM\JoinColumn(name="fruit_id", referencedColumnName="id")},
          *         inverseJoinColumns={@ORM\JoinColumn(name="country_id", referencedColumnName="id")}
          * ) 
          * @var Fruit[]
          */
          protected $fruits;
     }
    

    请注意,您不需要 countryFruits 类,但表 country_fruits 是必需的!

    【讨论】:

    • 我知道这有点老了,但是如果您想在连接表中存储其他信息,例如谁添加了什么水果以及添加时间,该怎么办?你还能定义那个实体并做这个连接表吗?
    • 您只需创建 2 * n:1 关系然后
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 2015-12-28
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多