2010-04-20 3 views
62

В доктрине вы можете создать DQL 2-мя способами:doctrine: QueryBuilder vs createQuery?

EntityManager :: CreateQuery:

$query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.id = ?1'); 

QueryBuilder:

$qb->add('select', 'u') 
    ->add('from', 'User u') 
    ->add('where', 'u.id = ?1') 
    ->add('orderBy', 'u.name ASC'); 

Интересно, что разница есть, и которые должны Я использую?

ответ

60
  1. DQL легче читать, так как он очень похож на SQL. Если вам не нужно менять запрос в зависимости от набора параметров, это, вероятно, лучший выбор.

  2. Query Builder - это api для создания запросов, поэтому вам проще построить запрос динамически, как итерацию по набору параметров или фильтров. Вам не нужно выполнять какие-либо строковые операции для создания вашего запроса, например, объединения, разделения или чего-то еще.

+0

Но нет ли накладных расходов на разбор строки DQL в первом случае? Или построитель также создает ту же строку DQL? –

+2

Да, QueryBuilder создает для вас строку DQL. После этого DQL разбирается в любом случае. – Dennis

31

Query Builder просто, позволяет сказать, интерфейс для создания запроса ... Он должен быть более удобным в использовании, она не только добавить() метод, но и методы, такие как, где(), andWhere (), from() и т. д. Но в итоге он просто составляет запрос, подобный тому, который вы используете в методе createQuery().

пример более продвинутого использования конструктора запросов:

$em->createQueryBuilder() 
      ->from('Project\Entities\Item', 'i') 
      ->select("i, e") 
      ->join("i.entity", 'e') 
      ->where("i.lang = :lang AND e.album = :album") 
      ->setParameter('lang', $lang) 
      ->setParameter('album', $album); 
+0

вы можете добавить -> setParameters (array ('x' => 'y', 'z' => 'w', ...)) –

13

Они имеют разные цели:

  • DQL проще в использовании, когда вы знаете свой полный запрос.
  • Query Builder умнее, когда вы должны построить свой запрос на основе некоторых условий, петли и т.д.
4

Основным отличием является то накладные расходы вызова методов. Ваш первый пример кода (createQuery) просто для простоты вызывает один вызов метода, в то время как queryBuilder делает 4. В конце всего, они сводятся к строке, которая должна быть выполнена, в первом примере вы даете ей строку, и другой вы строите его с помощью вызовов с несколькими цепями.

Если вы ищете причину использовать один над другим, это вопрос стиля и того, что выглядит более читаемым. Для меня мне больше нравится queryBuider, он предоставляет четко определенные разделы для запроса. Кроме того, в прошлом это упрощало добавление в условную логику, когда вам это нужно.

+0

Небольшое наблюдение - я бы сказал, что почти каждый раз, когда кто-то проводит в любом количестве вызовов функций PHP, связанных с SQLing, всегда будет менее критичным, чем время, затрачиваемое на беседу, ожидая и вытаскивая фактический результат из БД (не говоря уже о гидратации тех, в случае ORM). – userfuser

1

Может быть проще выполнить единичный тест при использовании построителя запросов. Допустим, у вас есть репозиторий, который запрашивает некоторые данные на основе сложного списка условий. И вы хотите заверить, что если какое-то конкретное условие передается в репозиторий, в запрос добавляются другие условия. В случае DQL у вас есть два варианта:

1) Использовать светильники и протестировать реальное взаимодействие с БД. Который я нахожу несколько хлопотным и неистовым.

2) Проверить сгенерированный код DQL. Что может сделать ваш тест слишком хрупким.

С QueryBuilder вы можете подставить его с помощью mock и убедиться, что метод «andWhere» с нужным параметром вызывается. Конечно, такие соображения неприменимы, если ваш запрос прост и не зависит от каких-либо параметров.

Смежные вопросы