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-07-12
Merci pour ce billet ! Il m'a bien dépanné.
Mathieu 27-07-12
Merci beaucoup ! c'est exactement ce dont j'avais besoin !
Ontsy 29-10-12
Mille merci, J'ai cherché partout mais j'ai trouvé ce qu'il me faut.
Yann 13-05-14
Merci pour ce tuto. ça fonctionne parfaitement.
Nico 11-06-14
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); ...

Ajouter un commentaire

Si vous souhaitez une réponse par mail.

Recherche

Détails de l'article