在使用Doctrine進行了一對多的映射,如一個人(Person),有多個小孩(Children),希望在使用Doctrine自動獲取Children時,小孩能按年齡大小排序。
請問:要重載哪個函數才能實現呢? persion->getChildren()呼叫了哪個函數進行SQL查詢呢?
這樣的需求,很難搜尋到結果,求前輩指點。
修改Person类的getChildren方法
Person
getChildren
<?php // src/AppBundle/Entity/Person.php // ... use Doctrine\Common\Collections\Criteria; //... /** * @param string $orderedByAge "ASC"|"DESC" */ public function getChildren($orderedByAge=null) { if (null === $orderedByAge) { return $this->children; } if (!in_array(strtoupper($orderedByAge), ['ASC', 'DESC'])) { throw new \InvalidArgumentException('参数错误,必须是"ASC"或"DESC"中的一个'); } $order = 'ASC' === $orderedByAge ? Criteria::ASC : Criteria::DESC; $criteria = Criteria::create()->orderBy(['age' => $order]); return $this->children->matching($criteria); } // ...
如果不想修改getChildren方法,可以写一个新的方法getChildrenOrderedByAge,道理同上。
getChildrenOrderedByAge
Doctrine的一对多或者多对多关系中,Entity中所谓多的属性是DoctrineCommonCollectionsCollection接口的某一实现的实例,默认情况下是DoctrineCommonCollectionsArrayCollection,上述解决方案中用到的就是这一接口的Filtering API(筛选接口),上述情况下,筛选的条件会最终转化到SQL層進行處理,以達到效能最佳化的目的。
Doctrine
Entity
多
DoctrineCommonCollectionsCollection
DoctrineCommonCollectionsArrayCollection
Filtering API
SQL
最後,相關官方文件連結如下:Filtering Collections
使用 @vinzao 的方式沒問題,不過 Doctirne 是提供了 OrderBy 方法的:
OrderBy
Person:
<?php // src/AppBundle/Entity/Person.php class Person { /** * @ORM\OneToMany(targetEntity="AppBundle\Entity\Children", mappedBy="person") * @ORM\OrderBy({"age"="DESC"}) */ protected $childrens; }
Children:
<?php // src/AppBundle/Entity/Children.php class Children { /** * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Person", inversedBy="childrens") */ protected $person; }
解決方案如下:
修改
Person
类的getChildren
方法如果不想修改
getChildren
方法,可以写一个新的方法getChildrenOrderedByAge
,道理同上。總結:
Doctrine
的一对多或者多对多关系中,Entity
中所谓多
的属性是DoctrineCommonCollectionsCollection
接口的某一实现的实例,默认情况下是DoctrineCommonCollectionsArrayCollection
,上述解决方案中用到的就是这一接口的Filtering API
(筛选接口),上述情况下,筛选的条件会最终转化到SQL
層進行處理,以達到效能最佳化的目的。最後,相關官方文件連結如下:Filtering Collections
使用 @vinzao 的方式沒問題,不過 Doctirne 是提供了
OrderBy
方法的:Person:
Children: