symfony2和doctrine填充来自api,关系创建的数据

时间:2015-11-02 17:07:10

标签: symfony doctrine relationships

我将来自外部api的数据存储到doctrine中,我已经为各种API调用创建了表。

为了使问题简单,我将解释几个实体:

  • 玩家 - 存储可供选择的玩家的信息(有 一个玩家ID)
  • 游戏 - 将要玩的游戏列表(有一个GameID)
  • PlayerGame - 为特定游戏存储玩家的统计数据(有一个 PlayerID和GameID)

我的问题是关于定义关系,以及是否从api调用中持久化数据足以产生关系。

我坚持播放器Feed和游戏Feed中的数据

当我为PlayerGame提取数据并持续存在(它具有playerID和GameID,这将是一个ManyToOne关系)时,这会通过持久保存来自Feed的数据来正确引用相关数据吗?

只是简单地定义实体中的关系,以确保我可以执行类似$ player-> getGames()的内容

额外信息

我已经建立了负责创建我需要保留的实体的构建器:

<?php

namespace FantasyPro\DataBundle\Builder;

use FantasyPro\DataBundle\Entity\Player;
use FantasyPro\DataBundle\Helpers\DateHelper;

class PlayerBuilder
{
    /**
     * @var DateHelper $dateHelper
     */
    private $dateHelper;

    public function __construct( DateHelper $dateHelper )
    {
        $this->dateHelper = $dateHelper;
    }

    public function buildPlayer( $currentPlayer = null, $player )
    {
        if ( ! $currentPlayer) {
            $currentPlayer = new Player();
        }

        // set the new values for the player
        $currentPlayer->setPlayerID( $player['PlayerID'] );
        $currentPlayer->setTeam( $player['Team'] );
        $currentPlayer->setNumber( $player['Number'] );
        $currentPlayer->setFirstName( $player['FirstName'] );
        $currentPlayer->setLastName( $player['LastName'] );
        $currentPlayer->setPosition( $player['Position'] );
        $currentPlayer->setStatus( $player['Status'] );
        $currentPlayer->setHeight( $player['Height'] );
        $currentPlayer->setWeight( $player['Weight'] );
        $currentPlayer->setBirthDate( $this->dateHelper->parseDate( $player['BirthDate'] ) );
        $currentPlayer->setCollege( $player['College'] );
        $currentPlayer->setExperience( $player['Experience'] );
        $currentPlayer->setFantasyPosition( $player['FantasyPosition'] );
        $currentPlayer->setActive( $player['Active'] );
        $currentPlayer->setPositionCategory( $player['PositionCategory'] );
        $currentPlayer->setName( $player['Name'] );
        $currentPlayer->setAge( $player['Age'] );
        $currentPlayer->setExperienceString( $player['ExperienceString'] );
        $currentPlayer->setBirthDateString( $player['BirthDateString'] );
        $currentPlayer->setPhotoUrl( $player['PhotoUrl'] );
        $currentPlayer->setByeWeek( $player['ByeWeek'] );
        $currentPlayer->setUpcomingGameOpponent( $player['UpcomingGameOpponent'] );
        $currentPlayer->setUpcomingGameWeek( $player['UpcomingGameWeek'] );
        $currentPlayer->setShortName( $player['ShortName'] );
        $currentPlayer->setAverageDraftPosition( $player['AverageDraftPosition'] );
        $currentPlayer->setDepthPositionCategory( $player['DepthPositionCategory'] );
        $currentPlayer->setDepthPosition( $player['DepthPosition'] );
        $currentPlayer->setDepthOrder( $player['DepthOrder'] );
        $currentPlayer->setDepthDisplayOrder( $player['DepthDisplayOrder'] );
        $currentPlayer->setCurrentTeam( $player['CurrentTeam'] );
        $currentPlayer->setCollegeDraftTeam( $player['CollegeDraftTeam'] );
        $currentPlayer->setCollegeDraftYear( $player['CollegeDraftYear'] );
        $currentPlayer->setCollegeDraftRound( $player['CollegeDraftRound'] );
        $currentPlayer->setCollegeDraftPick( $player['CollegeDraftPick'] );
        $currentPlayer->setIsUndraftedFreeAgent( $player['IsUndraftedFreeAgent'] );
        $currentPlayer->setHeightFeet( $player['HeightFeet'] );
        $currentPlayer->setHeightInches( $player['HeightInches'] );
        $currentPlayer->setUpcomingOpponentRank( $player['UpcomingOpponentRank'] );
        $currentPlayer->setUpcomingOpponentPositionRank( $player['UpcomingOpponentPositionRank'] );
        $currentPlayer->setCurrentStatus( $player['CurrentStatus'] );
        $currentPlayer->setUpcomingSalary( $player['UpcomingSalary'] );

        return $currentPlayer;
    }

}

坚持:

    namespace FantasyPro\DataBundle\Persisters;

    use Doctrine\ORM\EntityManager;
    use FantasyPro\DataBundle\Builder\PlayerBuilder;
    use FantasyPro\DataBundle\Entity\Player;

    class PlayerPersister
    {

        /**
         * @var EntityManager $em
         */
        private $em;
        /**
         * @var PlayerBuilder $builder
         */
        private $builder;

        public function __construct( EntityManager $em, PlayerBuilder $builder )
        {
            $this->em      = $em;
            $this->builder = $builder;
        }

        public function Persist( $player )
        {

            //get the player repository
            $repo = $this->em->getRepository( 'DataBundle:Player' );
            $uow  = $this->em->getUnitOfWork();

            // Set the current player to fetch from the db
            $criteria = array( 'playerID' => $player['PlayerID'] );

            //get the player from the repo
            /**
             * @var Player $currentPlayer
             */
            $currentPlayer = $repo->FindOneBy( $criteria );

            //build the player entity
            $currentPlayer = $this->builder->buildPlayer( $currentPlayer, $player );
            $exists        = $uow->isEntityScheduled( $currentPlayer );
            if ( ! $exists) {
                //persist the player
                $this->em->persist( $currentPlayer );

$this->em->flush();
                $this->em->clear();

            }

        }

我为Game和PlayerGame设置了这些设置

提供i使用正确的注释:

/**
     * @ORM\ManyToOne(targetEntity="FantasyPro\DataBundle\Entity\PlayerGame")
     * @ORM\JoinColumn(name="playerGame_playerID", referencedColumnName="playerID")
     */
    private $playerID;

使用ManyToMany会有什么用呢?

/**
     * @ORM\ManyToMany(targetEntity="FantasyPro\DataBundle\Entity\Player", inversedBy="playerID")
     * @ORM\JoinTable(
     *     name="player_playerGame",
     *     joinColumns={@ORM\JoinColumn(name="playerID", referencedColumnName="playerID", nullable=false)},
     *     inverseJoinColumns={@ORM\JoinColumn(name="playerGameID", referencedColumnName="playerGameID", nullable=false)}
     * )
     */
public $playerID;

我仍然可以使用构建器和persister我必须存储数据,所有内容都相关吗?

因此,为了确保实体存储正确,我可以使用PlayerGame的构建器:

// set the new values for the player
 $playerToStore = $em->getRepository('DataBundle:Player')->findBy($player['PlayerID']);

 $currentPlayer->setPlayerID( $playerToStore );

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您想知道,如果将从API直接提取的数据(通过SQL)存储到Doctrine,答案是肯定的。

您可以通过SQL填充表格,Doctrine将根据您的配置(例如注释)查找ID并加载实体。

如果您想要保留PlayerGame个实体,则必须为PlayerGame创建(或加载)实体,并使用PlayerGame中的设置者在致电persist()flush()之前实体。