2010-04-20 15 views
62

In Lehre können Sie DQL in zwei Arten erstellen:Doktrin: QueryBuilder vs createQuery?

EntityManager :: Create:

$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 die sollte Ich benutze?

Antwort

60
  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. Abfrage-Generator ist eine API, um Abfragen zu erstellen, also ist es einfacher, wenn Sie dynamisch eine Abfrage erstellen müssen, indem Sie über eine Reihe von Parametern oder Filtern iterieren. Sie müssen keine String-Operationen ausführen, um Ihre Abfrage wie Join, Split oder was auch immer zu erstellen.

+0

Aber gibt es keinen Overhead bei der Analyse der DQL-Zeichenfolge im ersten Fall? Oder der Builder erstellt als Ergebnis auch die gleiche DQL-Zeichenfolge? –

+2

Ja, QueryBuilder erstellt die DQL-Zeichenfolge für Sie. Danach wird DQL sowieso geparst. – Dennis

31

Query Builder ist nur erlaubt, sagt Schnittstelle Abfrage erstellen ... Es soll bequem sein, es zu benutzen hat nicht nur add() Methode, sondern auch Methoden wie where(), UndWo (), von(), usw. Aber am Ende wird nur eine Abfrage erstellt, wie sie in der createQuery() -Methode verwendet wird.

Beispiel für fortgeschrittenere Verwendung von Query Builder:

$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

können Sie hinzufügen -> setParameters (array ('x' => 'y', 'z' => 'w', ...)) –

13

Sie haben unterschiedliche Zwecke:

  • DQL einfacher zu verwenden, wenn Sie Ihre vollständige Abfrage kennen.
  • Query-Erstellung intelligenter, wenn Sie Ihre Abfrage basiert bauen auf einigen Bedingungen, Schleifen usw.
4

Der Hauptunterschied ist der Aufwand, die Methoden des Aufrufs. Ihr erstes Codebeispiel (createQuery) macht der Einfachheit halber einen Methodenaufruf, während der queryBuilder 4 macht. Am Ende von allem, kommen sie zu einem String, der ausgeführt werden muss, zum ersten Beispiel geben Sie ihm den String und das andere erstellen Sie mit mehreren verketteten Methodenaufrufen.

Wenn Sie einen Grund suchen, einen über den anderen zu verwenden, ist das eine Frage des Stils und was lesbarer aussieht. Für mich mag ich den QueryBuider die meiste Zeit, es bietet gut definierte Abschnitte für die Abfrage. In der Vergangenheit ist es außerdem einfacher, bedingte Logik hinzuzufügen, wenn Sie sie benötigen.

+0

Eine kleine Beobachtung - ich würde sagen, dass fast jede Zeit in einer beliebigen Anzahl verbringt PHP-Funktionsaufrufe im Zusammenhang mit SQLing werden immer weniger kritisch sein als die Zeit, die man mit dem Sprechen, Warten und Ziehen des tatsächlichen Ergebnisses aus der DB (ganz zu schweigen von deren Hydratisierung im Fall von ORMs) verbracht hat. – userfuser

1

Es kann einfacher sein, Komponententests durchzuführen, wenn der Abfrage-Generator verwendet wird. Nehmen wir an, Sie haben ein Repository, das einige Daten basierend auf der komplizierten Liste von Bedingungen abfragt. Und Sie möchten sicherstellen, dass, wenn eine bestimmte Bedingung in das Repository übergeben wird, einige andere Bedingungen in der Abfrage hinzugefügt werden. Im Falle von 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 unehrlich finde.

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

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