使用Doctrine 2和Zend Framework 2,使用一对多关系将实体保存在数据库中

时间:2012-10-02 15:07:34

标签: database doctrine-orm zend-form zend-framework2

我有一个直截了当的问题,但由于它与Doctrine 2和Zend Forms捆绑在一起,试试这里以获得专家的支持。

让我从我的实体开始 团队实体:

/**
 *
 * @ORM\Entity
 * @ORM\Table(name="team")
 * @property string $teamName
 * @property int $teamId
 */
class Team
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="teamId", unique=true);
     */
    protected $teamId;

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

    /**
     * @ORM\OneToMany(targetEntity="TeamPlayers", mappedBy="team", cascade={"persist"})
     */
    protected $player;

    /**
     * Magic getter to expose protected properties.
     *
     * @param string $property
     * @return mixed
     */
     public function __get($property)
    {
        return $this->$property;
    }

    /**
     * Magic setter to save protected properties.
     *
     * @param string $property
     * @param mixed $value
     */
    public function __set($property, $value)
    {
        $this->$property = $value;
    }
}

玩家实体:

/**
 *
 * @ORM\Entity
 * @ORM\Table(name="player")
 * @property string $playerName
 * @property int $playerId
 */
class Player
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="playerId", unique=true);
     */
    protected $playerId;

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

    /**
     * @ORM\OneToMany(targetEntity="TeamPlayers", mappedBy="player", cascade={"persist"})
     */
    protected $team;

    /**
     * Magic getter to expose protected properties.
     *
     * @param string $property
     * @return mixed
     */
     public function __get($property)
    {
        return $this->$property;
    }

    /**
     * Magic setter to save protected properties.
     *
     * @param string $property
     * @param mixed $value
     */
    public function __set($property, $value)
    {
        $this->$property = $value;
    }
}

TeamPlayer实体:

/**
 *
 * @ORM\Entity
 * @ORM\Table(name="teamplayer")
 * @property int $teamId
 * @property int $playerId
 */
class TeamPlayer 
{
    /**
     * @ORM\Id
     * @Column(type="integer")
     */
    protected $playerId;

    /**
     * @ORM\Id
     * @Column(type="integer")
     */
    protected $teamId;

    /**
     * @ORM\ManyToOne(targetEntity="Team", inversedBy="player", cascade={"persist"})
     */
    protected $team;

    /**
     * @ORM\ManyToOne(targetEntity="Player", inversedBy="team", cascade={"persist"})
     */
    protected $player;


    /**
     * Set player
     *
     * @param \Entity\Player $player
     */
    public function setPlayer(\Entity\Player $player)
    {
        $this->player = $player;
    }

    /**
     * Get player
     *
     * @return  \Entity\Player
     */
    public function getPlayer()
    {
        return  $this->player;
    }

    /**
     * Set team
     *
     * @param \Entity\Team $team     
     */
    public function setTeam(\Entity\Team $team)
    {
        $this->team = $team;
    }

    /**
     * Get team
     *
     * @return \Entity\Team     
     */
    public function getTeam()
    {
        return $this->team;
    }
}

?>

所以我现在最初有Zend Forms用于添加玩家,另一个用于添加团队,用户可以添加团队名称和团队ID,最后他可以为特定团队选择玩家,即一个团队可以有很多球员。因此,在添加到团队之前,用户可以选择表单中的多个玩家。

我在addAction()中使用我的控制器中的选定播放器添加团队时的问题,我如何处理这些关系映射,是否需要添加更多方法来更新teamplayer表。如果有人解释如何在控制器中执行此操作,对于像我这样的人越来越多地使用Zend和Doctrine会非常有帮助。

修改

*Player Table:*

playerId    -- int      -- PK, AI -- Unique
playerName  -- varchar  -- Unique


*Team Table:*

teamId    -- int      -- PK -- Unique
teamName  -- varchar  -- Unique

*TeamPlayer Table:*

playerId  -- int  -- PK, FK -- references player.playerId
teamId    -- int  -- PK, FK -- references team.teamId

P.S。我知道如何为单个表持久保存对象或使用Doctrine中的连接获取数据,但我不知道如何使用表之间的这种关系来保存实体。所以请将此视为学习者问题。

1 个答案:

答案 0 :(得分:0)

除了您的协会错误之外,在您的模型设计中,TeamPlayer实体将是两个关联的拥有方。所以你必须做这样的事情:

$teamPlayer = new TeamPlayer;
$teamPlayer->setPlayer($player);
$teamPlayer->setTeam($team);

$entityManager->persist($teamPlayer);
$entityManager->flush(); 

<强> BUT

查看ManyToMany关联,它将使您的关联和代码更易读,更少写。

玩家方关联的示例:

/**
 * @ManyToMany(targetEntity="Team")
 * @JoinTable(name="Team_Player",
 *      joinColumns={@JoinColumn(name="Player_id", referencedColumnName="id")},
 *      inverseJoinColumns={@JoinColumn(name="Team_id", referencedColumnName="id")}
 *      )
 */
protected $teams;

还要检查doctrine documentation for ManyToMany