Symfony : – Gestion des entités

Doctrine fournit des outils performants et flexibles pour gérer les entités et interagir avec la base de données. Cette section explore comment récupérer, manipuler, et optimiser les requêtes pour les entités grâce aux repositories, au DQL (Doctrine Query Language), et au QueryBuilder.

 Le Repository : Centralisateur de Requêtes

a. Rôle du Repository

Un repository centralise toutes les requêtes liées à une entité spécifique. Bien que majoritairement utilisé pour des opérations de lecture (SELECT), il peut également contenir des méthodes pour insérer, modifier, ou supprimer des données.

Chaque entité dispose de son propre repository. Si aucun repository personnalisé n’est défini, Doctrine utilise une classe par défaut. Pour accéder au repository d’une entité, vous pouvez utiliser l’EntityManager et sa méthode getRepository().

$repository = $this->em->getRepository(App\Entity\Livre::class);
$livre = $repository->find(1);

Dans cet exemple :

  • getRepository() récupère le repository lié à l’entité Livre.
  • find() retourne l’entité dont la clé primaire vaut 1.

b. Méthodes de Base

Doctrine fournit des méthodes intégrées pour effectuer des requêtes courantes :

  1. find($id)
    • Récupère une entité par sa clé primaire.
    • Exemple :
      $livre = $repository->find(15);
      
  2. findAll()
    • Retourne toutes les entités persistées en base sous forme de tableau.
  3. findOneBy(array $criteria)
    • Recherche une entité correspondant aux critères spécifiés.
    • Exemple :
      $livre = $repository->findOneBy(['titre' => '1984']);
      
  4. findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    • Recherche plusieurs entités selon des critères, avec des options de tri et de pagination.
    • Exemple :
      $livres = $repository->findBy(
          ['auteur' => 'George Orwell'],
          ['dateParution' => 'DESC'],
          10,
          0
      );
      

c. Repositories Personnalisés

Pour des besoins spécifiques, il est possible de créer des repositories personnalisés en étendant EntityRepository :

  1. Définir le Repository
    namespace App\Repository;
    
    use Doctrine\ORM\EntityRepository;
    
    class LivreRepository extends EntityRepository
    {
        public function rechercherParAuteur($auteur)
        {
            return $this->createQueryBuilder('l')
                        ->andWhere('l.auteur = :auteur')
                        ->setParameter('auteur', $auteur)
                        ->getQuery()
                        ->getResult();
        }
    }
    
  2. Associer le Repository à l’Entité
    #[ORM\Entity(repositoryClass: LivreRepository::class)]
    class Livre
    {
        // ...
    }
    

Le DQL : Doctrine Query Language

Le DQL est un langage de requête inspiré du SQL mais conçu pour interagir avec les entités et leurs relations. Doctrine traduit automatiquement ces requêtes DQL en SQL pour la base de données.

a. Syntaxe de Base

  • SELECT : Permet de récupérer des entités.
  • FROM : Définit l’entité principale.
  • WHERE : Applique des filtres.
  • JOIN : Réalise des jointures.

Exemple simple :

$query = $this->em->createQuery('SELECT l FROM App\Entity\Livre l WHERE l.titre = :titre');
$query->setParameter('titre', '1984');
$livre = $query->getOneOrNullResult();

b. Jointures

Les jointures permettent de récupérer des entités liées sans écrire plusieurs requêtes.

$query = $this->em->createQuery(
    'SELECT l, a FROM App\Entity\Livre l JOIN l.auteur a WHERE a.nom = :nom'
);
$query->setParameter('nom', 'Orwell');
$livres = $query->getResult();
  • JOIN : Jointure obligatoire.
  • LEFT JOIN : Jointure optionnelle.

c. Paramètres

Les paramètres rendent les requêtes dynamiques et sécurisées. Vous pouvez utiliser :

  • Paramètres nominatifs (:nom) :
    $query->setParameter('nom', 'Orwell');
    
  • Paramètres numérotés (?1) :
    $query->setParameter(1, 'Orwell');
    

Le QueryBuilder

Le QueryBuilder est un outil puissant et lisible pour construire dynamiquement des requêtes DQL. Il évite les erreurs liées à la concaténation manuelle des chaînes de requêtes.

a. Exemple Basique

$qb = $this->em->createQueryBuilder();
$qb->select('l')
   ->from('App\Entity\Livre', 'l')
   ->where('l.auteur = :auteur')
   ->setParameter('auteur', 'Orwell');

b. Requête Dynamique

Ajoutez des conditions de manière conditionnelle :

$qb = $this->em->createQueryBuilder('l');

if ($pseudo) {
    $qb->andWhere('l.pseudo LIKE :pseudo')
       ->setParameter('pseudo', '%'.$pseudo.'%');
}

return $qb->getQuery()->getResult();

c. Documentation

Consultez la documentation officielle pour plus d’informations : QueryBuilder – Doctrine

Pagination avec Doctrine

Doctrine ne propose pas de LIMIT directement en DQL. Cependant, l’objet Query offre des méthodes pratiques :

  • setMaxResults() : Limite le nombre de résultats.
  • setFirstResult() : Définit un décalage pour la pagination.

Exemple :

$query = $this->em->createQuery('SELECT l FROM App\Entity\Livre l ORDER BY l.id');
$query->setFirstResult(($page - 1) * $nbParPage)
      ->setMaxResults($nbParPage);

Recommandations 

  1. Évitez les Requêtes Non Optimisées :
    • Les jointures implicites (lazy loading) peuvent générer un grand nombre de requêtes SQL.
    • Utilisez des jointures explicites avec JOIN pour limiter les appels.
  2. Cachez les Résultats des Requêtes :
    • Doctrine permet de mettre en cache les résultats pour améliorer les performances des applications lourdes.
  3. Utilisez les Outils de Debug Symfony :
    • Le profiler Symfony affiche le nombre de requêtes SQL exécutées.
  4. Référez-vous à la Documentation Officielle :

Les repositories, le DQL et le QueryBuilder offrent une grande souplesse pour interagir avec vos entités et optimiser vos requêtes. En combinant ces outils avec des bonnes pratiques comme le cache et les jointures explicites, vous pouvez gérer efficacement les données dans une application Symfony robuste et évolutive.

Sites Ressources e-Plus Pour Laravel 11

1. Packagist Description : Le principal dépôt de packages PHP, avec une catégorie spécifique pour Laravel. Lien : https://packagist.org Ressources :...