Doctrine是否支持关联实体自动预查询的findBy内置方法?
嘿,好问题!其实Doctrine ORM本身就支持直接用关联实体的ID作为查询条件,完全不需要先手动查询关联实体再执行findBy——这应该就是你想要的“内置方法”了,而且比你当前的实现更高效。
核心知识点:Doctrine支持用关联ID直接查询
当你的实体(比如GroceryEntity)有一个关联字段(比如supplier指向SupplierEntity)时,Doctrine的findBy方法接受两种类型的条件值:
- 完整的关联实体对象(就是你之前用的
$slaveEntity) - 关联实体的主键值(比如
456)
也就是说,你完全可以跳过查询SupplierEntity的步骤,直接写:
$groceryRepo = $this->container->get('doctrine')->getRepository('AppBundle:GroceryEntity'); // 直接用供应商ID作为supplier字段的查询条件 $groceries = $groceryRepo->findBy(['supplier' => 456]);
Doctrine会自动帮你生成正确的SQL,通过关联字段的外键去匹配供应商ID,全程只需要一次数据库查询,比你原来两次查询的方式性能更好。
分页的处理
如果你需要分页,findBy本身就支持limit和offset参数,直接传入即可,不用自己计算total和start:
$pageSize = 10; $pageNumber = 1; $groceries = $groceryRepo->findBy( ['supplier' => 456], [], // 可选:排序条件,比如['id' => 'DESC'] $pageSize, // 每页数量 ($pageNumber - 1) * $pageSize // 偏移量 );
优化你的通用方法(如果需要)
如果你还是想封装一个通用的方法来处理这类关联查询,可以去掉查询关联实体的步骤,直接用ID作为条件,简化代码的同时提升性能:
public function findByAssociatedId( string $targetRepository, string $associationField, int $associatedId, int $limit = 0, int $offset = 0 ) { $repo = $this->container->get('doctrine')->getRepository("AppBundle:$targetRepository"); $criteria = [$associationField => $associatedId]; // 处理分页参数,0表示不限制 $findByLimit = $limit > 0 ? $limit : null; $findByOffset = $offset > 0 ? $offset : null; return $repo->findBy($criteria, [], $findByLimit, $findByOffset); }
调用的时候就变成:
$groceries = $DAO->findByAssociatedId('GroceryEntity', 'supplier', 456, 10, 0);
特殊情况:复合主键关联
如果你的关联实体用的是复合主键,那确实需要传入完整的实体对象(因为单ID无法唯一标识),但这种场景比较少见,大部分单主键场景下用ID直接查询就足够了。
内容的提问来源于stack exchange,提问作者Carlos Gonzalez
相关产品推荐
相关产品推荐

