Les Repository
Comme nous avons pu le voir auparavant, Symfony créer un repository pour chaque Entité.
Ce repository vient avec plusieurs avantages :
- Queries telles que
findAll
,findOneBy
... sont présente par défaut pour toutes nos entités - Possibilité de définir vos propres query et faire des traitement personnalisés
C'est ici le deuxième avantage qui va nous intéressé le plus, car les queries par défaut sont puissantes, mais ne couvrent pas tous les cas que l'on voudrait !
Pour définir une nouvelle custom query définissez une nouvelle méthode dans votre fichier repository (ici par exemeple MonkeyRepository.php
)
<?php
namespace App\Repository;
use App\Entity\MonkeyRespository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
/**
* @method MonkeyRespository|null find($id, $lockMode = null, $lockVersion = null)
* @method MonkeyRespository|null findOneBy(array $criteria, array $orderBy = null)
* @method MonkeyRespository[] findAll()
* @method MonkeyRespository[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class MonkeyRespository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Monkey::class);
}
public function findAllMaleMonkey() {
return [];
}
}
Vous pouvez désormais l'utiliser dans votre code de cette manière là (fichier controller de Monkey) :
use App/Entity/Monkey;
/// ... code
public function list (EntityManagerInterface $em) {
$repository = $em->getRepository(Monkey::class);
$monkeys = $repository->findAllMaleMonkey(); // On l'utilise de la même manière que les autres fonctions !
if(!$monkeys) {
throw $this->createNotFoundException('Sorry, no monkey came for the banana this time');
}
return $this->render('monkey.html.twig', [
"monkeys" => $monkeys
]);
}
Les custom queries s'utilisent de la même manière que les queries normales, toutes celle qui sont présentes dans le repository de la classe, vous seront disponible comme cela
Bon, pour le moment ça ne nous sert pas à grand chose on renvoie un tableau vide !
Mais comme vous avez pu le voir dans les méthodes mises en commentaire dans votre repository, vous pouvez faire bien plus ici, grâce au query builder !
⚠️Attention, quand vous créez une query avec le query builder, le repository assume que vous allez faire une requête sur la table liée à l'entité
Un query builder s'organise de cette façon là :
<?php
namespace App\Repository;
use App\Entity\MonkeyRespository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
/**
* @method MonkeyRespository|null find($id, $lockMode = null, $lockVersion = null)
* @method MonkeyRespository|null findOneBy(array $criteria, array $orderBy = null)
* @method MonkeyRespository[] findAll()
* @method MonkeyRespository[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class MonkeyRespository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Monkey::class);
}
public function findAllMaleMonkey() {
return $this->createQueryBuilder('m') // m pour "monkey"
->andWhere('m.sexe = :sexe') // on défini le paramètre de requête
->setParameter('sexe', 'M') // on défini le paramètre dynamique
->orderBy('s.nom', 'ASC') // On défini ici l'ordre de tri
->setMaxResults(10) // Récupération de 10 élément maximum
->getQuery() // Récupération de la query
->getResult() // Récupération du résultat de la query
}
}
Ici vous avez donc une query pour récupérer tous les Monkey de types mal !
La syntaxe est faite pour coller au plus proche du SQL pour faire comme si vous créiez une vériable requête sql.
Vous trouverez toutes la documentation et les possibilités du query builder sur la documentation de doctrine à ce sujet
Vous pouvez aussi utiliser du DQL, qui est plus proche du SQL, mais nous ne le verrons pas dans le cadre de ce cours
Petites particularités
Vous avez peut être pu remarqué des choses comme andWhere
dans la custom query ?
C'est tout à fait normal, where
et andWhere
sont très similaires, la première permet seulement d'en mettre une seule, alors que la seconde plusieurs à la suite.
Il est donc une bonne pratique d'utiliser andWhere
dès le premier pour éviter de réfléchir si vous allez en avoir plusieurs ou non !
Conclustion
C'est tout ? Oui, tout n'a pas besoin d'être compliqué !
Afin de bien comprendre comment faire ces custom query de la meilleure manière possible, je vous conseille vivement de lire attentivement documentation de doctrine à ce sujet comme défini plus haut, de cette manière vous aurez connaissances de toutes les possibilités !