web-dev-qa-db-ja.com

findAll Doctrineのメソッドをソートする方法

私はDoctrineのドキュメントを読んでいますが、findAll()の結果をソートする方法を見つけることができませんでした。

私はsymfony2 + doctrineを使用しています。これはコントローラー内で使用しているステートメントです。

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

しかし、結果をユーザー名の昇順で並べたいです。

私はこの方法で引数として配列を渡そうとしました:

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

しかし、それは機能しません(文句を言いません)。

DQLクエリを作成せずにこれを行う方法はありますか?

97
ILikeTacos

示されているように@Lighthartのように、可能ですが、コントローラーにかなりの脂肪を追加し、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();
202
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);
75
Stiig

シンプル:

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

時々ソースコードを見ると便利です。

たとえば、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)
20
luchaninov

これは私のために働く:

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

最初の配列を空のままにすると、すべてのデータが取得され、私の場合はうまくいきました。

6
Buttler

次のような基準を使用する必要があります。

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

Doctrine AP​​Iソースコードを見てください:

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

これを試して:

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

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

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句よりも高速で、イテレータのオーバーヘッドがありません。

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()メソッドを作成するためにリポジトリに配置できる関数に簡単に変換できます。

2
nifr

symfonyのfindByメソッドは、2つのパラメーターを除きます。 1つ目は検索するフィールドの配列で、2つ目の配列は並べ替えフィールドとその順序です

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

EntityRepositoryのデフォルトのfindAll関数を次のように変更します。

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

そのように、クエリを並べ替えるオプションを使用して、任意のデータテーブルの任意のクエリで '' findAll ''を使用できます

0
niksa