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

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

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');

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

Ответ 1

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

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

Ответ 2

Конструктор запросов - это, скажем, интерфейс для создания запроса... Он должен быть более удобен в использовании, он не имеет метода add(), но также методы, такие как where() и Where(), 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);

Ответ 3

У них разные цели:

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

Ответ 4

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

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

Ответ 5

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

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

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

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