2

Doctrine 2 是否支持自动 JOIN 生成?也就是说,假设我有一个与一些产品实体相关联的卖家实体,每个产品实体都有一个类别,做类似的事情

$sellers = $entityManager->getRepository('Foo\Bar\Seller')->findBy(array('country' => 'US'), array('populate' => array('Product', 'Product.Category')));
foreach ($sellers as $seller) {
    doStuffWith($seller->product->category);
}

整个事情只需要一个查询,因为 Doctrine 会将产品和类别表加入到卖家表中,并使用结果来预填充关联。这样的事情可能吗?

4

2 回答 2

3

您有两种方法可以自动执行 JOIN:

  • 使用急切获取
  • 使用 DQL

Eager fetching 意味着每当获取主实体时,Doctrine 2 也会自动获取任何标记为“eager”的关系。这是通过使用fetch映射中的属性来完成的(参见手册:ManyToOne

使用 DQL,您需要编写一个同时获取主实体和相关实体/实体的查询:

SELECT m, r FROM My\MainEntity m LEFT JOIN m.relatedEntity r

Eager fetching 与 DQL 相比的好处在于,通过 Eager fetch,您将基本上自动获得该功能。但是,Eager fetching 的缺点是,如果您实际上不使用相关实体,则可能会导致性能损失。使用 DQL,您始终可以控制获取的内容和时间。

于 2012-05-18T15:05:23.893 回答
0

来自Doctrine Query Language 文档

初学者的一个常见错误是将 DQL 误认为只是某种形式的 SQL,因此试图在查询中使用表名和列名或将任意表连接在一起。您需要将 DQL 视为对象模型的查询语言,而不是关系模式的查询语言。

如果你想使用对象(实体),每个都有自己的存储库,你不应该考虑 SQL(或JOINing 表),因为存储库和DQL 查询将始终只返回单一类型的 object
ORM 的目的是让您将其视为对象(而不是表),而无需考虑持久层的技术实现:考虑关联,而不是joins;必要的 SQL 查询会根据需要在后台自动执行,而无需过多考虑过早的优化(Doctrine 对性能并不理想;但有时许多查询可能比一个大的单个连接查询更快)。

如果您从多个 SQL 表(如此多种类型)获取连接数据,那么您的查询结果记录不再代表每个单个/唯一对象,而是每个记录是来自多个表并涉及多个模型的数据的混搭。

如果您进行查询,ORM 应该映射什么实体SELECT seller.*, product.name, product.price, category.name FROM ..
只是映射到卖方?缺少属性的产品?
应该从 SQL 结果的每条记录映射哪个单个实体,例如:

+-----------+-------------+-----------------+---------------+-----------------+
| seller.id | seller.name |  product.name   | product.price |  category.name  |
+-----------+-------------+-----------------+---------------+-----------------+
|        42 | Alan Smith  | Apple MacBook   | 1500$         | Computer&Mobile |
|        42 | Alan Smith  | Apple MacBook   | 1850$         | Computer&Mobile |
|        42 | Alan Smith  | Dell XPS        | 1500$         | Computer&Mobile |
|        34 | Jane Foley  | Clarinet Selmer | 1720$         | Music           |
+-----------+-------------+-----------------+---------------+-----------------+

?

ORM 无法猜测!

因此,您需要一个自定义映射器来告诉 Doctrine 如何从包含混合数据的 SQL 行中构建实体对象(模型)。
查看Native SQL 文档,了解如何构建自己的ResultSetMapping.

于 2021-09-06T22:01:54.020 回答