Symfony 6中能否用findBy()实现ManyToOne关联表查询?
问题解答
1. 能否通过findBy()实现关联查询?
完全可以用findBy()实现,不需要必须使用createQuery()。针对A与B的ManyToOne关联关系,只需在查询条件中通过关联属性的点式语法指定关联实体的字段即可。比如假设A实体中关联B的属性名为$b,B实体中存储状态的字段为$status,查询代码如下:
$aRecords = $this->getDoctrine()->getRepository(A::class)->findBy([ 'b.status' => 'private' ]);
Doctrine Repository默认的findBy()方法原生支持这种关联字段的查询方式,你自定义的findBy()方法逻辑和默认实现一致,同样可以使用该语法。
2. 返回字段不一致的原因与解决办法
你的推测是正确的:findBy()返回的是完整实体对象,会遵守实体类上的#[Ignore]注解,序列化时自动跳过标记字段;而createQuery()如果返回数组或手动指定字段,不会识别这些注解,导致字段输出不一致。
要统一返回字段,有两种简洁方案:
- 让
createQuery()返回完整实体对象,例如编写JPQL:
这样返回的A实体对象会和$query = $this->_em->createQuery( 'SELECT a FROM App\Entity\A a JOIN a.b b WHERE b.status = :status' )->setParameter('status', 'private'); $aRecords = $query->getResult();findBy()的结果一样,序列化时自动遵守#[Ignore]注解。 - 若需自定义返回字段,可通过反射读取实体的
#[Ignore]注解,在查询后统一过滤字段,但这种方式需要额外代码,不如返回实体对象高效。
3. 关于自定义的findBy()方法
你当前的自定义findBy()方法仅调用底层persister->loadAll(),逻辑与Doctrine默认实现一致,无需修改即可支持关联字段的点式查询,直接使用上述条件就能得到目标结果。
内容的提问来源于stack exchange,提问作者Davide Nascimento
相关产品推荐
相关产品推荐

