доктрина: QueryBuilder против createQuery?

В Doctrine вы можете создать DQL двумя способами:

EntityManager::createQuery:

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

Построитель запросов:

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

Интересно, в чем разница и что я должен использовать?


person never_had_a_name    schedule 20.04.2010    source источник


Ответы (5)


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

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

person jackbravo    schedule 09.12.2010
comment
Но нет ли накладных расходов на синтаксический анализ строки DQL в первом случае? Или в результате сборщик также создает ту же строку DQL? - person Alexey Kosov; 03.12.2014
comment
Да, QueryBuilder создает для вас строку DQL. После этого DQL все равно анализируется. - person Dennis; 07.10.2015

Конструктор запросов - это просто, скажем так, интерфейс для создания запроса... Он должен быть более удобным в использовании, у него есть не только метод add(), но и такие методы, как where(), 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);
person Martin Kočička    schedule 09.12.2010
comment
вы можете добавить -›setParameters(array('x' => 'y', 'z' => 'w', ...)) - person Herr Nentu'; 15.09.2015

У них разное назначение:

  • DQL проще использовать, когда вы знаете свой полный запрос.
  • Конструктор запросов умнее, когда вам нужно построить свой запрос на основе некоторых условий, циклов и т. д.
person Vincent Pazeller    schedule 16.08.2012

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

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

person NiteRain    schedule 05.06.2014
comment
Небольшое наблюдение: я бы сказал, что почти любое время, затрачиваемое на любое количество вызовов функций PHP, связанных с SQL, всегда будет менее критичным, чем время, потраченное на разговоры, ожидание и извлечение фактического результата из БД (не для упомянуть их увлажнение в случае ORM). - person userfuser; 30.01.2018

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

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

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

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

person Dienow    schedule 07.04.2015