学说:QueryBuilder与createQuery?


70

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

我想知道区别是什么,应该使用哪个?

Answers:


68
  1. DQL与SQL非常相似,因此更易于阅读。如果您不需要根据一组参数来更改查询,那么这可能是最佳选择。

  2. Query Builder是用于构造查询的api,因此,如果您需要动态地构建查询(例如遍历一组参数或过滤器),则会更容易。您无需执行任何字符串操作即可构建查询,例如join,split等。


1
但是在第一种情况下解析DQL字符串是否没有开销?还是生成器也会生成相同的DQL字符串?
阿列克谢·科索夫

4
是的,QueryBuilder为您创建DQL字符串。之后,无论如何都要解析DQL。
丹尼斯

33

可以说,查询生成器只是创建查询的接口...使用起来应该更舒适,它不仅具有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);

1
您可以添加-> setParameters(array('x'=>'y','z'=>'w',...))
Nentu先生'15

14

它们具有不同的目的:

  • 当您知道完整的查询时,DQL易于使用。
  • 当您必须根据某些条件,循环等来构建查询时,查询构建器会更聪明。

4

主要区别是调用方法的开销。为了简单起见,您的第一个代码示例(createQuery)进行了一个方法调用,而queryBuilder进行了4。在所有内容的最后,它们都归结为必须执行的字符串,第一个示例是给它提供字符串,然后另一个是您通过多个链接方法调用来构建它。

如果您要寻找一个在另一个上使用的理由,那就是样式问题,什么看起来更易读。对我而言,我大部分时间都喜欢queryBuider,它为查询提供了定义明确的部分。同样,在过去,它使在需要时添加条件逻辑变得更加容易。


一个小小的观察-我要说的是,几乎任何时候花在与SQLing相关的任意数量的PHP函数调用上的时间,总是比花在与DB进行交谈,等待和提取实际结果上的时间要紧(而不是花在数据库上)。如果是ORM,请提及为它们补水)。
userfuser

1

使用查询生成器时,进行单元测试可能会更容易。假设您有一个存储库,可以根据复杂的条件列表查询一些数据。并且您想确保如果将特定条件传递到存储库中,则将其他一些条件添加到查询中。对于DQL,您有两种选择:

1)使用固定装置并测试与DB的真实交互。我觉得这有些麻烦和不公正。

2)检查生成的DQL代码。这会使您的测试过于脆弱。

使用QueryBuilder,您可以用模拟代替它,并验证是否调用了具有所需参数的“ andWhere”方法。当然,如果您的查询简单且不依赖任何参数,则这些注意事项将不适用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.