Gestion des parenthèse avec le QueryBuilder de Doctrine 2

Voici un snippet Doctrine2 pour gérer les parenthèses dans la clause WHERE d'une requete SQL à l'aide du QueryBuilder.

La requête cible est:

 
SELECT m.*, p.*
FROM Message m
INNER JOIN Product p ON m.id = p.mes_id
WHERE  m.delDate IS NULL
AND ( p.module IS NULL OR p.module = 'RAC')

Vous l'aurez compris, la problèmatique se situe au niveau de la dernière ligne de la requête SQL. Ce serait simple à écrire en DQL mais s'il on a besoin de la couche d'abstraction du DQL via l'objet QueryBuidler, ça se complique un peu.
Pour gérer les parenthése avec l'objet QueryBuilder de Doctrine 2, on ne peut pas directement utiliser les méthode where(), andWhere() ou orWhere(). Il faut passer par la création d'une Expression de type OR dans mon cas. Il suffit ensuite d'ajouter les associations champs / valeur puis d'ajouter le tout à la requête avec la méthode where().

 
$em = $this->getDoctrine()->getEntityManager();
$qb = $em->createQueryBuilder();
 
$qb->from('TestBundle:Message', 'm')
       ->join('m.product', 'p')
       ->where('m.delDate IS NULL');
 
//création de l'expression OR
$orModule = $qb->expr()->orx();
$orModule->add($qb->expr()->eq('p.module', ':module'));
$orModule->add($qb->expr()->isNull('p.module'));
 
//Ajout de l'expression à la requête			
$qb->andWhere($orModule)
       ->setParameter('module', 'RAF', \PDO::PARAM_STR);
 
$r = $qb->getQuery()->getResult();

C'est finalement assez simple mais je n'en ai pas trouvé de trace dans la documentation.

Il y a 5 commentaires.

Maxime Bernard 16 juil. 2012
Merci pour ce billet ! Il m'a bien dépanné.
Mathieu 27 juil. 2012
Merci beaucoup ! c'est exactement ce dont j'avais besoin !
Ontsy 29 oct. 2012
Mille merci, J'ai cherché partout mais j'ai trouvé ce qu'il me faut.
Yann 13 mai 2014
Merci pour ce tuto. ça fonctionne parfaitement.
Nico 11 juin 2014
Post toujours d'actualité, documentation officielle toujours peu claire à sujet ... Merci beaucoup ;) Il est bien sur possible d'effectuer des (x = x AND a = a) OR (x = y AND a = b) grâce à : $andMod = $qb->expr()->andX(); $andMod->addMultiple(array( $qb->expr()->eq('i.class_name', ':class'.$cpt), $qb->expr()->in('i.id_in_scope', $ids) )); $qb->setParameter(':class'.$cpt, $class); $qb->orWhere($andMod); ...

L'ajout de commentaire est temporairement désactivé à cause du spam.

Recherche

Détails de l'article