2013-06-14 5 views
79

Doctrine의 문서를 읽었지만 findAll() 결과를 정렬 할 수있는 방법을 찾지 못했습니다. 내가 symfony2 + 교리를 사용하고findAll Doctrine의 메소드 정렬 방법

, 이쪽은 내 컨트롤러 내부에 사용하고 문입니다 :

$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();

하지만 결과가 사용자 이름을 오름차순으로 정렬되어야합니다.

findAll(array('username' => 'ASC'));

을하지만 (이 중 하나 불평하지 않습니다) 작동하지 않습니다

내가 인수로 이런 식으로 배열을 전달하기 위해 노력했습니다.

DQL 쿼리를 작성하지 않고이를 수행 할 수있는 방법이 있습니까?

답변

158

는 컨트롤러에 상당한 지방을 추가하고 DRY 아니지만, 그래 그것이 가능합니다.

엔티티 리포지토리에서 고유 한 쿼리를 정의해야합니다. 간단하고 모범 사례입니다.

use Doctrine\ORM\EntityRepository; 

class UserRepository extends EntityRepository 
{ 
    public function findAll() 
    { 
     return $this->findBy(array(), array('username' => 'ASC')); 
    } 
} 

는 그런 다음 저장소에 쿼리를 찾기 위해 당신의 실체를 알려야합니다 :

/** 
* @ORM\Table(name="User") 
* @ORM\Entity(repositoryClass="Acme\UserBundle\Entity\Repository\UserRepository") 
*/ 
class User 
{ 
    ... 
} 

마지막으로, 컨트롤러 :

$this->getDoctrine()->getRepository('AcmeBundle:User')->findAll(); 
+1

이것은 내 방식보다 나은 접근 방법이지만 dql을 작성할 것입니다. 내 방법은 dql이 적기 때문에 OP의 제약 조건에 응답합니다. 솔직히 dql에 대한 두려움은 극복되어야합니다. 가능하면이 방법을 우선적으로 사용하십시오. – Lighthart

+0

글쎄 dql에 대한 두려움이 아니며이 답변을 읽기 전에 궁극적으로 DQL을 사용하여이 작업을 수행했지만 DQL이 없기 때문에 처음에는 DQL을 사용하지 않으려 고했습니다. 컨트롤러가 이미 가지고있는 코드 스타일. 이 솔루션은 저에게 정말 좋습니다! – ILikeTacos

+1

@ Pier-Luc Gendreau 너무 간단해서 똑똑해. – pregmatch

5

당신은 예를 들어, 기준을 사용해야합니다

같이 @Lighthart으로
<?php 

namespace Bundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Doctrine\Common\Collections\Criteria; 

/** 
* Thing controller 
*/ 
class ThingController extends Controller 
{ 
    public function thingsAction(Request $request, $id) 
    { 
     $ids=explode(',',$id); 
     $criteria = new Criteria(null, <<DQL ordering expression>>, null, null); 

     $rep = $this->getDoctrine()->getManager()->getRepository('Bundle:Thing'); 
     $things = $rep->matching($criteria); 
     return $this->render('Bundle:Thing:things.html.twig', [ 
      'entities' => $things, 
     ]); 
    } 
} 
2

당신은 배열을 사용하여 기존의 ArrayCollection을 정렬 할 수 있습니다 반복자.

은 $ 수집을 가정하는 것은

$iterator = $collection->getIterator(); 
$iterator->uasort(function ($a, $b) { 
    return ($a->getPropery() < $b->getProperty()) ? -1 : 1; 
}); 
$collection = new ArrayCollection(iterator_to_array($iterator)); 

이 쉽게 findAllOrderBy() 메소드를 만들기 위해 당신이 당신의 저장소에 넣을 수있는 기능으로 설정할 수 있습니다 findall은에 의해 반환 당신의 ArrayCollection()입니다.

+4

여기에 가리 키시겠습니까? 이것에 대한 충분한 유스 케이스가 있습니다 ... 즉, PHP에서 이미 가져온 콜렉션을 정렬하는 것은 정렬을 위해 또 다른 mysql 쿼리를 수행하는 것보다 항상 빠릅니다! 하나의 페이지에서 두 개의 서로 다른 정렬 스타일로 동일한 콜렉션 데이터를 출력해야한다고 가정 해보십시오 ... – nifr

+2

일반적으로 정렬 된 쿼리를 반환하는 것은 데이터베이스의 작업이어야합니다. OTOH,이 기술은 더 복잡한 경우 nifr 언급에 적용 할 수 있습니다. – Lighthart

58
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']); 
+0

이 솔루션은 간단합니다. –

+0

매우 간단한 해결책, 고마워 striiig –

2

저는 nifr을 작성한 솔루션 대신 사용할 수 있습니다.

$resultRows = $repository->fetchAll(); 
uasort($resultRows, function($a, $b){ 
    if ($a->getProperty() == $b->getProperty()) { 
     return 0; 
    } 
    return ($a->getProperty()< $b->getProperty()) ? -1 : 1; 
}); 

그것은 BY 절 ORDER보다 더 빨리, 그리고 반복자의 오버 헤드없이.

+1

그것은 나를 위해 일했다! –

4

이 나를 위해 작동합니다

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(),array('name' => 'ASC')); 

빈 다시 모든 데이터를 가져 오는 첫 번째 배열을 유지, 내 경우했다.

2

이 시도 :

$em = $this->getDoctrine()->getManager(); 

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC')); 
18

때때로 소스 코드를 볼 유용합니다.findAll 구현이 매우 간단합니다 예를 들어

(vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php) :

public function findAll() 
{ 
    return $this->findBy(array()); 
} 

그래서 우리는 findBy을보고 우리는 교리의 API 소스 코드에서 (orderBy)

public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) 
4

봐 원하는 것을 찾는 :

class EntityRepository{ 
    ... 
    public function findAll(){ 
    return $this->findBy(array()); 
    } 
    ... 
} 
7

단순 :

$this->getDoctrine()->getRepository('AcmeBundle:User')->findBy(
    array(), 
    array('username' => 'ASC') 
);