findAll Doctrine의 방법을 정렬하는 방법


111

나는 Doctrine의 문서를 읽고 있었지만 findAll () 결과를 정렬하는 방법을 찾지 못했습니다.

나는 symfony2 + doctrine을 사용하고 있습니다. 이것은 컨트롤러 내부에서 사용하고있는 진술입니다.

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

하지만 결과가 오름차순 사용자 이름으로 정렬되기를 원합니다.

이 방법으로 배열을 인수로 전달하려고했습니다.

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

그러나 그것은 작동하지 않습니다 (그것도 불평하지 않습니다).

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

답변:


229

@Lighthart와 같이 컨트롤러에 상당한 지방을 추가하고 건조하지는 않지만 가능합니다.

엔터티 저장소에서 자신의 쿼리를 정의해야합니다. 간단하고 모범 사례입니다.

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();

2
이것은 내 것보다 더 나은 접근 방식이지만 dql을 작성하게 될 것입니다. 내 방법은 dql이 적으므로 OP의 제약에 응답합니다. 솔직히, dql에 대한 두려움은 극복되어야합니다. 가능하다면이 방법을 선호하여 사용하십시오.
Lighthart

글쎄, 그것은 dql에 대한 두려움이 아닙니다. 컨트롤러가 이미 가지고있는 코드 스타일. 이 솔루션은 저에게 정말 좋습니다!
ILikeTacos 2013-06-15

1
또는 간단히 : $ this-> getDoctrine ()-> getRepository ( 'AcmeBundle : User')-> findBy (array (), array ( 'username'=> 'ASC'));
Benji_X80

1
@ Benji_X80 그 원 라이너는 확실히 짧지 만 전혀 DRY가 아닙니다. findAll 메소드는 컨트롤러가 아닌 저장소에 속합니다.
Pier-Luc Gendreau 2014 년

1
주석을 사용하는 것 외에 다른 방법으로 사용자 지정 저장소에서 쿼리를 찾도록 엔티티에 지시 할 수 있습니까? 그것은 내가 본 것 중 가장 끔찍한 프로그래밍 습관이다
세자 누스

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

24

단순한:

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

이것은 매력처럼 작동했습니다! 그리고 아직도 심포니 4 바로이 방식으로 작동합니다
로버트 Saylor

20

때때로 소스 코드를 보는 것이 유용합니다.

예를 들어 findAll구현은 매우 간단합니다 ( vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php).

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

그래서 우리는 findBy우리에게 필요한 것을보고 찾습니다. ( orderBy)

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

6

이것은 나를 위해 작동합니다.

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

첫 번째 배열을 비워두면 모든 데이터를 가져 오지만 제 경우에는 작동했습니다.


5

Doctrine API 소스 코드를 살펴보십시오.

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

이 코드 조각은 아무것도 정렬하지 않습니다
Nico Haase

5

다음과 같은 기준을 사용해야합니다.

<?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,
        ]);
    }
}

4

Symfony의 findBy 메소드는 두 개의 매개 변수를 제외합니다. 첫 번째는 검색하려는 필드의 배열이고 두 번째 배열은 정렬 필드와 그 순서입니다.

public function findSorted()
    {
        return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
    }

매우 짧은 답변에 설명을 추가 할 수 있습니까?
Nico Haase 2018

아주 짧은 대답입니다. 정교-설명 ... 편집 .
Paul Hodges

그것은 완벽한 대답이었습니다! findBy (array (), array ( 'fieldname'=> 'ASC') 이것은 모두를 찾아 표시된 방향으로 필드를 정렬합니다
Robert Saylor

2

배열 반복기를 사용하여 기존 ArrayCollection을 정렬 할 수 있습니다.

$ collection이 findAll ()에 의해 반환 된 ArrayCollection이라고 가정합니다.

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

이것은 findAllOrderBy () 메소드를 생성하기 위해 저장소에 넣을 수있는 함수로 쉽게 변환 될 수 있습니다.


4
여기서 당신의 요점은 무엇입니까? 이것에 대한 충분한 사용 사례가 있습니다. 즉, PHP에서 이미 가져온 컬렉션을 정렬하는 것이 정렬을 위해 다른 mysql 쿼리를 수행하는 것보다 항상 빠릅니다! ... 당신이 한 페이지에 출력에 두 개의 서로 다른 정렬 스타일에서 동일한 수집 데이터가 필요 상상
니콜라이 Fröhlich에게

2
일반적으로 정렬 된 쿼리를 반환하는 것이 데이터베이스의 작업이어야합니다. OTOH,이 기술은 nifr이 언급 한 더 많은 관련 사례에 적용 할 수 있습니다.
Lighthart 2014 년

2

이 시도:

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

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

1

nifr을 작성한 솔루션의 대안을 사용합니다.

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

ORDER BY 절 보다 빠르고 Iterator의 오버 헤드가 없습니다.


답변에 추가 설명을 추가하십시오. 애플리케이션에서 정렬하는 것이 데이터베이스 수준에서 수행하는 것보다 어떻게 더 빠를 수 있습니까?
Nico Haase

0

다음과 같이 EntityRepository에서 기본 findAll 함수를 수정합니다.

public function findAll( array $orderBy = null )
{
    return $this->findBy([], $orderBy);
}

이렇게하면 쿼리를 정렬하는 옵션이있는 데이터 테이블의 모든 쿼리에서 ''findAll ''을 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.