Doktrin: QueryBuilder vs createQuery?

70

In Doctrine können Sie DQL auf zwei Arten erstellen:

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

Ich frage mich, was der Unterschied ist und welchen ich verwenden soll.

Never_had_a_name
quelle

Antworten:

68
  1. DQL ist einfacher zu lesen, da es SQL sehr ähnlich ist. Wenn Sie die Abfrage nicht abhängig von einer Reihe von Parametern ändern müssen, ist dies wahrscheinlich die beste Wahl.

  2. Der Abfrage-Generator ist eine API zum Erstellen von Abfragen. Daher ist es einfacher, wenn Sie eine Abfrage dynamisch erstellen müssen, z. B. über eine Reihe von Parametern oder Filtern iterieren. Sie müssen keine Zeichenfolgenoperationen ausführen, um Ihre Abfrage wie Join, Split oder was auch immer zu erstellen.

Jackbravo
quelle
1
Aber ist das Parsen von DQL-Strings im ersten Fall nicht mit einem Overhead verbunden? Oder macht der Builder auch den gleichen DQL-String?
Alexey Kosov
4
Ja, QueryBuilder erstellt die DQL-Zeichenfolge für Sie. Danach wird DQL sowieso analysiert.
Dennis
33

Der Abfrage-Generator ist beispielsweise eine Schnittstelle zum Erstellen von Abfragen ... Er sollte komfortabler zu verwenden sein und verfügt nicht nur über die Methode add (), sondern auch über Methoden wie where () und Where (), from () usw. Am Ende wird jedoch nur eine Abfrage erstellt, wie Sie sie in der Methode createQuery () verwenden.

Beispiel für eine erweiterte Verwendung des Abfrage-Generators:

$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);
Martin Kočička
quelle
1
Sie können hinzufügen -> setParameters (Array ('x' => 'y', 'z' => 'w', ...))
Herr Nentu
14

Sie haben unterschiedliche Zwecke:

  • DQL ist einfacher zu verwenden, wenn Sie Ihre vollständige Abfrage kennen.
  • Der Abfrage-Generator ist intelligenter, wenn Sie Ihre Abfrage basierend auf bestimmten Bedingungen, Schleifen usw. erstellen müssen.
Vincent Pazeller
quelle
4

Der Hauptunterschied ist der Aufwand für den Aufruf der Methoden. Ihr erstes Codebeispiel (createQuery) führt der Einfachheit halber einen Methodenaufruf aus, während der queryBuilder 4 ausführt. Am Ende von allem kommt es auf eine Zeichenfolge an, die ausgeführt werden muss. Im ersten Beispiel geben Sie ihm die Zeichenfolge und Das andere erstellen Sie mit mehreren verketteten Methodenaufrufen.

Wenn Sie nach einem Grund suchen, einen über den anderen zu verwenden, ist dies eine Frage des Stils und dessen, was besser lesbar aussieht. Für mich gefällt der queryBuider die meiste Zeit, er bietet gut definierte Abschnitte für die Abfrage. In der Vergangenheit war es außerdem einfacher, bedingte Logik hinzuzufügen, wenn Sie sie benötigen.

NiteRain
quelle
Eine kleine Beobachtung - ich würde sagen, dass fast jede Zeit, die man mit einer beliebigen Anzahl von PHP-Funktionsaufrufen im Zusammenhang mit SQLing verbringt, immer weniger kritisch ist als die Zeit, die für das Sprechen, Warten und Abrufen des tatsächlichen Ergebnisses aus der Datenbank aufgewendet wird (nicht für Erwähnen Sie die Hydratation bei ORMs.
Userfuser
1

Mit dem Abfrage-Generator ist es möglicherweise einfacher, einen Komponententest durchzuführen. Angenommen, Sie haben ein Repository, das anhand der komplizierten Liste von Bedingungen nach Daten fragt. Und Sie möchten sicherstellen, dass der Abfrage einige andere Bedingungen hinzugefügt werden, wenn eine bestimmte Bedingung an das Repository übergeben wird. Bei DQL haben Sie zwei Möglichkeiten:

1) Um Fixtures zu verwenden und die reale Interaktion mit DB zu testen. Was ich etwas lästig und uneinheitlich finde.

2) Um den generierten DQL-Code zu überprüfen. Was Ihren Test zu zerbrechlich machen kann.

Mit QueryBuilder können Sie es durch mock ersetzen und überprüfen, ob die Methode "andWhere" mit dem erforderlichen Parameter aufgerufen wird. Natürlich sind solche Überlegungen nicht anwendbar, wenn Ihre Abfrage einfach ist und nicht von Parametern abhängt.

Stirb jetzt
quelle