Aller au contenu principal

SQL dans un repository

Comment utiliser le langage SQL dans une méthode d'un repository pour faire des requêtes dans la base de données

Notions théoriques

Bien que Doctrine offre des méthodes puissantes pour interroger la base de données, il peut parfois être nécessaire d'écrire des requêtes SQL brutes pour des cas d'utilisation spécifiques ou pour des raisons de performance.

Symfony 7 permet d'exécuter facilement des requêtes SQL personnalisées au sein d'un repository.

Les principales raisons d'utiliser du SQL brut sont :

  • Optimisation des performances pour des requêtes simples
  • Utilisation de fonctions spécifiques à la base de données
  • Exécution de requêtes qui ne correspondent pas au modèle objet de Doctrine

Dans Symfony 7, nous utilisons l'injection de dépendances pour accéder à l'EntityManager dans nos repositories, ce qui nous permet d'exécuter des requêtes SQL brutes.

Exemple de mise en application

Voici un exemple de repository utilisant une requête SQL brute simple dans Symfony 7 :

use App\Entity\Player;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;

class PlayerRepository extends ServiceEntityRepository
{
private $entityManager;

public function __construct(ManagerRegistry $registry, EntityManagerInterface $entityManager)
{
parent::__construct($registry, Player::class);
$this->entityManager = $entityManager;
}

public function findTopPlayers($limit = 10)
{
$conn = $this->entityManager->getConnection();

$sql = '
SELECT id, name, score
FROM player
ORDER BY score DESC
LIMIT :limit
';

$stmt = $conn->prepare($sql);
$result = $stmt->executeQuery(['limit' => $limit]);

return $result->fetchAllAssociative();
}
}

Etudions ce code

$conn = $this->entityManager->getConnection();

Cette ligne récupère la connexion à la base de données à partir de l'EntityManager injecté.

$sql = '
SELECT id, name, score
FROM player
ORDER BY score DESC
LIMIT :limit
';

Nous définissons notre requête SQL personnalisée. Elle sélectionne les joueurs, les trie par score décroissant et limite le nombre de résultats.

$stmt = $conn->prepare($sql);
$result = $stmt->executeQuery(['limit' => $limit]);

Nous préparons et exécutons la requête en passant le paramètre limit.

return $result->fetchAllAssociative();

Enfin, nous récupérons tous les résultats sous forme de tableau associatif.

Test de mémorisation/compréhension


Comment injecte-t-on l'EntityManager dans un repository Symfony 7 ?


Comment obtient-on la connexion à la base de données dans un repository Symfony 7 ?


Comment passe-t-on des paramètres à une requête SQL préparée dans Symfony 7 ?


Quelle clause SQL utilise-t-on pour limiter le nombre de résultats retournés ?


Quelle méthode utilise-t-on pour récupérer tous les résultats d'une requête SQL sous forme de tableau associatif dans Symfony 7 ?


TP pour réfléchir et résoudre des problèmes

Votre défi pour aujourd'hui consiste à écrire une requête SQL brute dans le repository.

Créez une méthode dans le PlayerRepository qui utilise une requête SQL brute pour récupérer les joueurs d'une catégorie spécifique, triés par score décroissant.

La méthode doit accepter la catégorie et une limite optionnelle comme paramètres.

Une solution