我将来自外部api的数据存储到doctrine中,我已经为各种API调用创建了表。
为了使问题简单,我将解释几个实体:
我的问题是关于定义关系,以及是否从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 );
答案 0 :(得分:1)
如果我理解正确,您想知道,如果将从API直接提取的数据(通过SQL)存储到Doctrine,答案是肯定的。
您可以通过SQL填充表格,Doctrine将根据您的配置(例如注释)查找ID并加载实体。
如果您想要保留PlayerGame
个实体,则必须为Player
和Game
创建(或加载)实体,并使用PlayerGame
中的设置者在致电persist()
和flush()
之前实体。