教义: QueryBuilder vs createQuery?

在 Doctrine 中,您可以通过两种方式创建 DQL:

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

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

58963 次浏览
  1. DQL 更容易阅读,因为它与 SQL 非常相似。如果您不需要根据一组参数更改查询,那么这可能是最佳选择。

  2. Query Builder 是一个构造查询的 api,所以如果需要动态构建查询,比如在一组参数或过滤器上迭代,那么构建查询会更容易。你不需要做任何字符串运算来构建你的查询,比如加入、分割或者其他什么。

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

它们有不同的目的:

  • 当您知道完整的查询时,DQL 更容易使用。
  • 当您必须基于某些条件、循环等构建查询时,查询生成器更聪明。

主要区别在于调用方法的开销。为了简单起见,第一个代码示例(createQuery)执行一个方法调用,而 queryBuilder 执行4个方法调用。在所有事情的最后,它们归结为一个必须执行的字符串,例如,首先给它一个字符串,然后用多个链式方法调用构建它。

如果你正在寻找一个使用一个而不是另一个的理由,这是一个风格的问题,什么看起来更可读。对我来说,大多数时候我喜欢 queryBuider,它为查询提供了定义良好的部分。而且,在过去,当你需要的时候,条件逻辑更容易添加。

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

1)使用 fixture 并测试与 DB 的真实交互。我觉得这有些麻烦和不统一。

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

使用 QueryBuilder,您可以使用 mock 替换它,并验证调用了带有所需参数的“ andWhere”方法。当然,如果查询很简单而且不依赖于任何参数,那么这些考虑因素是不适用的。