Doctrine 对一对多关系进行了许多查询
Posted
技术标签:
【中文标题】Doctrine 对一对多关系进行了许多查询【英文标题】:Doctrine makes many queries for one-to-many relationship 【发布时间】:2015-11-05 21:33:01 【问题描述】:我有一个使用 Doctrine 作为 ORM 的 Symfony2 应用程序。在我的应用程序中,我有两个具有一对多关系的实体。一个实体是User
,多个实体是Item
。他们的关系配置如下:
用户:
oneToMany:
items:
targetEntity: App\Bundle\ItemBundle\Entity\Item
fetch: EAGER
mappedBy: user
项目:
manyToOne:
user:
targetEntity: App\Bundle\UserBundle\Entity\User
fetch: EAGER
inversedBy: items
joinColumn:
name: user_id
referencedColumnName: id
问题是当我试图获取Users
和他们的Items
的列表时,Doctrine 会为每个用户创建单独的查询来获取它的项目。
查询本身非常简单:
$entities = $em->getRepository('AppUserBundle:User')->findBy([], [], 30);
是否可以使用 Doctrine 在一个查询中自动获取用户的所有相关项目?
我正在使用带有版本的 SF 2.7.6 和学说库:
doctrine/annotations v1.2.7 Docblock Annotations Parser
doctrine/cache v1.5.1 Caching library offering an ob...
doctrine/collections v1.3.0 Collections Abstraction library
doctrine/common v2.5.1 Common Library for Doctrine pr...
doctrine/dbal v2.5.2 Database Abstraction Layer
doctrine/doctrine-bundle 1.6.0 Symfony DoctrineBundle
doctrine/doctrine-cache-bundle 1.2.1 Symfony Bundle for Doctrine Cache
doctrine/doctrine-migrations-bundle 1.1.1 Symfony DoctrineMigrationsBundle
doctrine/inflector v1.0.1 Common String Manipulations wi...
doctrine/instantiator 1.0.5 A small, lightweight utility t...
doctrine/lexer v1.0.1 Base library for a lexer that ...
doctrine/migrations v1.1.0 Database Schema migrations usi...
doctrine/orm v2.5.1 Object-Relational-Mapper for php
【问题讨论】:
确保您已清除缓存并且您显示的映射文件是实际使用的文件。让您不混合 yaml 和注释。您发布的内容应该有效。 我刚刚检查了所有这些,但仍然没有运气。 只是为了笑,尝试从您的查询中删除 30。涉及连接时,限制和偏移总是有点挑战。 【参考方案1】:无论如何,我认为设置 Eager fetch 并不是一个好主意。
这样的东西应该可以正常工作:
$users = $this->getEntityManager()
->createQueryBuilder()->select('u, i') // key is to select both entities
->from('YourBundle:User', 'u')
->join('u.item', 'i')
->getQuery()->getResult();
【讨论】:
我已经设法使用您的答案获取相关记录。从技术上讲,它可以工作,但会在数据上产生很大的开销。假设我与用户实体有多个一对多关系,并且想要一次返回 10000 条记录,并且每个用户都有 10 个项目和 10 个帐户。如果我为此使用 JOIN 方法,它将返回 10000 * 10 * 10 条记录。如果 Doctrine 可以进行 3 个单独的查询来获取这些数据,我会更喜欢。【参考方案2】:您可以创建一个method in the repository 来执行连接以避免额外的查询。可以用您自己的实现替换 findBy
方法,但我更喜欢创建更具描述性的方法。
虽然 Symfony 文档中的示例使用 DQL,但如果您愿意,也可以使用 QueryBuilder
。
【讨论】:
我使用的是查询生成器,本题中的查询仅用于简化,结果是一样的。 如果您使用的是查询生成器,请发布查询。您将需要同时选择用户和项目。有很大的不同。以上是关于Doctrine 对一对多关系进行了许多查询的主要内容,如果未能解决你的问题,请参考以下文章