学说:ORM QueryBuilder 或 DBAL QueryBuilder

Posted

技术标签:

【中文标题】学说:ORM QueryBuilder 或 DBAL QueryBuilder【英文标题】:Doctrine: ORM QueryBuilder or DBAL QueryBuilder 【发布时间】:2016-08-25 21:09:53 【问题描述】:

DBAL 查询生成器: http://www.doctrine-project.org/api/dbal/2.3/class-Doctrine.DBAL.Query.QueryBuilder.html

ORM 查询构建器: http://www.doctrine-project.org/api/orm/2.3/class-Doctrine.ORM.QueryBuilder.html

在 Doctrine 内部有 2 个非常相似的 QueryBuilder,一个 DBAL 和一个 ORM。

这两个有什么区别?与 DBAL 相比,使用 ORM queryBuilder 是否有很大的开销?

(本地查询是不可能的,因为我需要使用动态 where 语句)

【问题讨论】:

【参考方案1】:

第一个用于 SQL 查询,第二个用于 DQL。

大多数情况下,从 EntityManager::createQueryBuilder() 获取 QueryBuilder 实例(可能通过 Repository 类,请参阅 EntityRepository;;createQueryBuilder()),在这种情况下,您将使用 Doctrine\ORM\QueryBuilder 并编写 DQL。

如果您需要运行 SQL 查询,您将使用 Doctrine\DBAL\QueryBuilder,实例通常从 Doctrine\DBAL\Connection::createQueryBuilder()EntityManager::getConnection() 检索。

您可以阅读更多关于the benefits of use DQL over SQL in doctrine (和反向)的信息。

【讨论】:

【参考方案2】:

如果您使用 ORM,请使用 ORM 之一。否则,您应该只使用 DBAL。您可以在下面找到有关他们实际工作的一些详细信息。

DBAL 代表数据库抽象层。它试图抽象出尽可能多的数据库特定内容,如驱动程序或查询语法,因此它们可以互换,而无需更改代码。

ORM 代表 Object Relational Mapping,它比 DBAL 更进一步,并尝试将数据库模式绑定到应用程序中的实际类。

这两个都带有查询生成器。 DBAL 查询构建器更基本,因为它只提供与多个驱动程序/数据库的兼容性。您仍然对表进行操作,并且仍然获得行作为结果。另一方面,ORM 查询构建器设计用于处理实体(数据库模式绑定到的类)。

例如,一个 DBAL 查询:

$builder->select('u.id, e.id, e.email')
    ->from('users', 'u')
    ->leftJoin('u', 'emails', 'e', 'u.id = e.user_id')
    ->where('u.id = :id')
    ->setParameter(':id', $id);

$rows = $builder->execute()->fetchAll();

在这里,我们创建一个查询,将users 表与emails 表连接起来,以获取ID 为$id 的用户的所有电子邮件地址。结果将采用关联数组的形式。现在让我们看一下ORM:

$builder->select('u','e')
    ->leftJoin('u.emails', 'e')
    ->where('u.id = :id')
    ->setParameter(':id', $id);

$user = $builder->getQuery()->getOneOrNullResult();

在这里,我们说我们想要获取 ID 为 $idUser 以及他所有的 Email 电子邮件地址。我们不在乎它们来自哪个表或它们之间的关系是什么。你得到的是一个User 类的实例,其中包含Email 对象的集合。由于 ORM 映射,所有这些都填充了正确的数据。

【讨论】:

还想指出,ORM 还支持native SQL queries 和自定义结果集映射。出于报告、聚合数据和类似目的,您应该避免使用 ORM 实体,而应使用表查询,以减少实体在实例化时提供的业务逻辑的固有开销。

以上是关于学说:ORM QueryBuilder 或 DBAL QueryBuilder的主要内容,如果未能解决你的问题,请参考以下文章

排除学说QueryBuilder中的重叠期

学说:QueryBuilder 存在的地方

学说:QueryBuilder 与 createQuery?

如何将这个简单的 sql 查询转换为学说 querybuilder

Symfony 2 实体连接或学说查询连接

如何在学说 ORM Symfony 4.1 中使用 array_agg?