Сложные предложения WHERE, использующие ORM PHP Doctrine ORM

Я использую ORM PHP Doctrine для создания моих запросов. Однако я не могу представить, как написать следующее предложение WHERE с использованием DQL (Doctrine Query Language):

WHERE name='ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X') AND price > 10 

Как указать, куда идут круглые скобки?

То, что у меня есть в моем PHP-коде, следующее:

 ->where('name = ?', 'ABC') ->andWhere('category1 = ?', 'X') ->orWhere('category2 = ?', 'X') ->orWhere('category3 = ?', 'X') ->andWhere('price > ?', 10) 

Но это создает что-то вроде

 WHERE name='ABC' AND category1 = 'X' OR category2 = 'X' OR category3 = 'X' AND price > 10 

который из-за порядка операций не возвращает ожидаемые результаты.

Кроме того, существует ли разница между методами «где», «и где» и «addWhere»?

UPDATE Итак, похоже, что вы не можете выполнять сложные запросы с использованием DQL, поэтому я пытаюсь написать SQL вручную и использовать метод andWhere () для его добавления. Тем не менее, я использую WHERE..IN и Doctrine, похоже, удаляет заключенные круглые скобки:

 $q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)"); 

Solutions Collecting From Web of "Сложные предложения WHERE, использующие ORM PHP Doctrine ORM"

По моему опыту, каждый комплекс, where функция сгруппирована в круглых скобках (я использую Doctrine 1.2.1).

 $q->where('name = ?', 'ABC') ->andWhere('category1 = ? OR category2 = ? OR category3 = ?', array('X', 'X', 'X')) ->andWhere('price < ?', 10) 

создает следующий SQL:

 WHERE name = 'ABC' AND (category1 = 'X' OR category2 = 'X' OR category3 = 'X') AND price < 10 

Правильный способ сделать это можно найти в doctrine 2 – условные запросы построителя запросов … Если инструкции? как отмечает @Jekis. Вот как использовать построитель выражений, чтобы решить это, как в примере @ 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); 

Похоже, что вы не можете выполнять сложные запросы с помощью DQL, я написал следующий SQL для перехода к методу andWhere ():

 $q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause) AND TRUE"); 

Обратите внимание на «И ИСТИННО», хак, чтобы анализатор не игнорировал внешние круглые скобки.

и где можно суммировать как:
Ранее добавленное условие (-ы)

Вы можете безопасно использовать и везде где . (он вводит очень малые накладные расходы, что указано ниже во втором элементе списка.)

Реализация andWhere: (Доктрина 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); } 

который можно читать как,

  1. Параметры процесса
  2. добавьте инструкцию AND к тому, где часть запроса, если другая, где оператор был добавлен до
  3. добавить условие

Что касается разницы между where, andwhere и addwhere, я не думаю, что есть существенное отличие от последнего раза, когда я читаю источник. Однако я бы рекомендовал вам прочитать источник Доктрины. Это очень просто, и помогает заполнять отверстия в документации (их много). Что касается сложных заявлений, я сам это задавал, но пока не нуждался в этом.

По моему опыту, я иногда видел разницу между:

 $q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)"); 

а также

 $q->andWhere("(category1 IN $subcategory_in_clause OR category2 IN $subcategory_in_clause OR category3 IN $subcategory_in_clause)"); 

Первое утверждение написано на 3 строках, второе – только на одном. Я не верил в это, но есть РАЗЛИЧИЯ!