27935 id = 27935 date = "2024-10-25 13:16:09" Score Riri 27935 id = 1 points = 11 Score Enide 27935 id = 2 points = 7 Score Raclo 27936 id = 3 points = 3 Score Riri 27936 id = 4 points = 11 Player Riri id = 1 name = "Riri" Player Raclo id = 2 name = "Raclo" Player Enide id = 3 name = "Enide"
27935 id = 27935 date = "2024-10-25 13:16:09" Score Riri 27935 id = 1 points = 11 Score Enide 27935 id = 2 points = 7 Score Raclo 27936 id = 3 points = 3 Score Riri 27936 id = 4 points = 11 Player Riri id = 1 name = "Riri" Player Raclo id = 2 name = "Raclo" Player Enide id = 3 name = "Enide"
27935 id = 27935 date = "2024-10-25 13:16:09" Score Riri 27935 id = 1 points = 11 Score Enide 27935 id = 2 points = 7 Score Raclo 27936 id = 3 points = 3 Score Riri 27936 id = 4 points = 11 Player Riri id = 1 name = "Antho" Player Raclo id = 2 name = "Raclo" Player Enide id = 3 name = "Enide"
#[ORM\Column(length: 255)] public string $name; #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
#[ORM\Column(length: 255)] public string $name; #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
'stats')] class Stats { #[ORM\Id] #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
#[ORM\Column(length: 255)] public string $name; #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
#[ORM\OneToOne(targetEntity: Player::class, fetch: 'EAGER')] #[ORM\JoinColumn(name: 'id')] public Player $player; #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
StatsRepository::class, readOnly: true)] #[ORM\Table(name: 'stats')] class Stats { #[ORM\Id] #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
#[ORM\OneToOne(targetEntity: Player::class, fetch: 'EAGER')] #[ORM\JoinColumn(name: 'id')] public Player $player; #[ORM\Column(name: 'nb_games')] public int $numberOfGames; #[ORM\Column(name: 'avg_points')] public float $averagePoints; }
Doctrine Ne pas oublier de filtrer le nom de la vue pour éviter les conflits avec Doctrine migration, schema:validate , etc dbal: schema_filter: ~^(?!stats)~
vue se comporte comme une entité ✔️ Hydratation ✔️ Relations avec d’autres entités (LAZY ou EAGER) ✔️ Possible de la requêter en DQL (pour filtrer le résultat par exemple) ❌ Pas de modifications (read-only)
player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT DISTINCT p.name FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 4
player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT DISTINCT p.name FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 4
p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 4 WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 )
s2.points WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT DISTINCT p.name FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 4
s2.points JOIN first_player ON first_player.id = s2.player_id WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT DISTINCT p.name FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id WHERE g.season_id = 4
player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT DISTINCT p.name FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 4
'p'); $selectClause = $rsmBuilder->generateSelectClause(['p']); $query = $this->_em->createNativeQuery(<<<SQL WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT $selectClause FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 2 SQL, $rsmBuilder); return $query->getResult(); }
FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT $selectClause FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 2 SQL, $rsmBuilder); public function getFirstPlayerWinners(): array { $rsmBuilder = new ResultSetMappingBuilder($this->_em); $rsmBuilder->addRootEntityFromClassMetadata(Player::class, 'p'); $selectClause = $rsmBuilder->generateSelectClause(['p']); return $query->getResult(); }
getFirstPlayerWinners(): array { $selectClause = $rsmBuilder->generateSelectClause(['p']); $query = $this->_em->createNativeQuery(<<<SQL WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT $selectClause FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 2 return $query->getResult(); }
$rsmBuilder = new ResultSetMappingBuilder($this->_em); $rsmBuilder->addRootEntityFromClassMetadata(Player::class, 'p'); $query = $this->_em->createNativeQuery(<<<SQL WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 2 SQL, $rsmBuilder); return $query->getResult(); }
'p'); $selectClause = $rsmBuilder->generateSelectClause(['p']); $query = $this->_em->createNativeQuery(<<<SQL WITH first_player AS ( SELECT player.id, player.current_player_season_id FROM player JOIN player_season on player.current_player_season_id = player_season.id ORDER BY player_season.elo DESC LIMIT 1 ) SELECT $selectClause FROM player p JOIN score s1 ON p.id = s1.player_id JOIN game g ON s1.game_id = g.id JOIN score s2 ON g.id = s2.game_id AND s1.points > s2.points JOIN first_player ON first_player.id = s2.player_id WHERE g.season_id = 2 SQL, $rsmBuilder); return $query->getResult(); }
) Réhydrater des vraies entités Possible de mixer entités, scalaires et DTO Vraiment intéressant quand la requête est complexe mais que le résultat reste une entité Utilisé en interne par Doctrine pour mapper les résultats des requêtes SQL aux entités