Où les clauses complexes utilisent la Doctrine PHP ORM
j'utilise L'ORM de Doctrine PHP pour construire mes requêtes. Cependant, je ne peux pas tout à fait comprendre comment écrire la clause suivante Où utiliser DQL (Doctrine Query Language):
WHERE name='ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
AND price > 10
Comment puis-je préciser où vont les parenthèses?
ce que j'ai actuellement dans mon code PHP est ceci:
->where('name = ?', 'ABC')
->andWhere('category1 = ?', 'X')
->orWhere('category2 = ?', 'X')
->orWhere('category3 = ?', 'X')
->andWhere('price > ?', 10)
mais cela produit quelque chose comme
WHERE name='ABC' AND category1 = 'X' OR category2 = 'X' OR category3 = 'X'
AND price > 10
qui, en raison de l'ordre des opérations, ne retourne pas les résultats escomptés.
Existe-t-il également une différence entre les méthodes" où"," et où "et" addWhere"?
mise à JOUR Ok, il semble que vous ne pouvez pas faire de requêtes complexes en utilisant DQL, donc j'ai essayé d'écrire le SQL manuellement et d'utiliser la méthode andWhere() pour l'ajouter. Cependant, J'utilise où...dans et la Doctrine semble enlever mon enclos entre parenthèses:
$q->andWhere("(category1 IN $subcategory_in_clause
OR category2 IN $subcategory_in_clause
OR category3 IN $subcategory_in_clause)");
6 réponses
D'après mon expérience, chaque fonction complexe where
est groupée entre parenthèses (J'utilise la Doctrine 1.2.1).
$q->where('name = ?', 'ABC')
->andWhere('category1 = ? OR category2 = ? OR category3 = ?', array('X', 'X', 'X'))
->andWhere('price < ?', 10)
produit le code SQL suivant:
WHERE name = 'ABC'
AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X')
AND price < 10
la bonne façon de faire cela peut être trouvée à doctrine 2 - requêtes conditionnelles builder... Si les déclarations? comme noté par @Jekis. Voici comment utiliser l'expression builder pour résoudre ce problème comme dans l'exemple de @anushr.
$qb->where($qb->expr()->eq('name', ':name'))
->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('category1', ':category1'),
$qb->expr()->eq('category2', ':category2'),
$qb->expr()->eq('category3', ':category3')
)
->andWhere($qb->expr()->lt('price', ':price')
->setParameter('name', 'ABC')
->setParameter('category1', 'X')
->setParameter('category2', 'X')
->setParameter('category3', 'X')
->setParameter('price', 10);
comme il semble que vous ne pouvez pas faire de requêtes complexes en utilisant DQL, J'ai écrit le SQL suivant pour passer à la méthode andWhere ():
$q->andWhere("(category1 IN $subcategory_in_clause
OR category2 IN $subcategory_in_clause
OR category3 IN $subcategory_in_clause) AND TRUE");
Notez le" and TRUE", un hack pour que l'analyseur n'ignore pas les parenthèses extérieures.
et où peut se résumer comme suit::
Condition(s) précédemment ajoutée (s) Aware WHERE Statement
vous pouvez utiliser en toute sécurité et partout au lieu de où . (il introduit un très petit plafond, qui est indiqué ci-dessous dans le point de la deuxième liste.)
La mise en œuvre de la et où est la suivante: (Doctrine 1.2.3)
public function andWhere($where, $params = array())
{
if (is_array($params)) {
$this->_params['where'] = array_merge($this->_params['where'], $params);
} else {
$this->_params['where'][] = $params;
}
if ($this->_hasDqlQueryPart('where')) {
$this->_addDqlQueryPart('where', 'AND', true);
}
return $this->_addDqlQueryPart('where', $where, true);
}
, qui se lit comme suit:,
- paramètres du procédé
- ajouter et ajouter où partie de la requête, si un autre où la déclaration a été ajoutée avant
- annexe condition
quant à la différence entre où, et où, et addwhere, Je ne crois pas qu'il y ait une différence significative par rapport à la dernière fois que j'ai lu la source. Je vous encourage cependant à lire la source de la Doctrine. C'est très simple, et permet remplit les trous dans la documentation (ils sont nombreux). En ce qui concerne les déclarations complexes, je me suis posé la question moi-même, mais je n'en ai pas encore eu besoin.
d'après mon expérience, j'ai parfois vu une différence entre:
$q->andWhere("(category1 IN $subcategory_in_clause
OR category2 IN $subcategory_in_clause
OR category3 IN $subcategory_in_clause)");
et
$q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)");
la première déclaration est écrite sur 3 lignes, la seconde, sur une seule. Je n'y croyais pas, mais il y a une différence !