symfony - 减少 Doctrine 中不必要的连接
问题描述
为简单起见,让 Symfony 中有 2 个实体。第一个被调用Job
,第二个被调用Field
(类别为Job
)。每个作业可以属于多个字段。Job
知道它的字段,而Field
实体对工作一无所知。
// Job.php
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Field")
* @ORM\JoinTable(name="job_to_fields",
* joinColumns={@ORM\JoinColumn(name="job_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="field_id", referencedColumnName="id")}
* )
*/
private $fields;
当我们想为 fields 加载所有工作时[1, 2, 3]
,我期望像
SELECT j.*
FROM job j
INNER JOIN job_to_fields jtf ON j.id = jtf.job_id
WHERE /* some other parameters */jtf.field_id IN (1, 2, 3)
实际上,Doctrine 构造了这个 SQL 语句:
SELECT j.*
FROM job j
INNER JOIN job_to_fields jtf ON j.id = jtf.job_id
INNER JOIN field f ON f.id = jtf.field_id
WHERE /* some other parameters */f.id IN (1, 2, 3)
第二个连接(到field
表)是不必要的。有没有办法删除这个/告诉教义不要这样做?
理论上,Doctrine 应该知道 and 的关系f.id
,jtf.field_id
因为它在连接中使用它们。
解决方案
这是正确的行为,因为没有getFields()
对 Job 对象的联接调用将无法访问要显示的数据。
您可能可以通过在 $fields 注释上使用惰性获取来影响这一点,但是如果您曾经调用 getFields() ,它将最终运行进一步的查询以获取数据。
@ORM\ManyToMany(targetEntity="App\Entity\Field", fetch="EXTRA_LAZY")
但是,除非您要解决特定问题,否则我会顺其自然。这是 ORM 在做 ORM 所做的事情。
推荐阅读
- node.js - 部署node js express应用-cent os
- php - redis连接成功时数据未发布到redis中
- nginx - nginx 请求应该去多个位置
- android - 无法理解 Lambda -> 运算符
- hyperledger-fabric - 在 Hyperledger Fabric 的多个组织中使用单个用户
- android - 我的应用程序在闲置一段时间后兑现
- javascript - Webpack - SyntaxError: Unexpected token {
- javascript - 如何在for循环内制作一个切换按钮以仅在单击的元素上激活
- python - 如何删除与列表元素相关的类型错误
- javascript - React 属性传播符号是否也传递给子代?