私はDoctrineのドキュメントを読んでいますが、findAll()の結果をソートする方法を見つけることができませんでした。
私はsymfony2 + doctrineを使用しています。これはコントローラー内で使用しているステートメントです。
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findAll();
しかし、結果をユーザー名の昇順で並べたいです。
私はこの方法で引数として配列を渡そうとしました:
findAll( array('username' => 'ASC') );
しかし、それは機能しません(文句を言いません)。
DQLクエリを作成せずにこれを行う方法はありますか?
示されているように@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();
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);
シンプル:
$this->getDoctrine()->getRepository('AcmeBundle:User')->findBy(
array(),
array('username' => 'ASC')
);
時々ソースコードを見ると便利です。
たとえば、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)
これは私のために働く:
$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(),array('name' => 'ASC'));
最初の配列を空のままにすると、すべてのデータが取得され、私の場合はうまくいきました。
次のような基準を使用する必要があります。
<?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,
]);
}
}
Doctrine APIソースコードを見てください:
class EntityRepository{
...
public function findAll(){
return $this->findBy(array());
}
...
}
これを試して:
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC'));
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句よりも高速で、イテレータのオーバーヘッドがありません。
配列反復子を使用して、既存の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()メソッドを作成するためにリポジトリに配置できる関数に簡単に変換できます。
symfonyのfindByメソッドは、2つのパラメーターを除きます。 1つ目は検索するフィールドの配列で、2つ目の配列は並べ替えフィールドとその順序です
public function findSorted()
{
return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
}
EntityRepositoryのデフォルトのfindAll関数を次のように変更します。
public function findAll( array $orderBy = null )
{
return $this->findBy([], $orderBy);
}
そのように、クエリを並べ替えるオプションを使用して、任意のデータテーブルの任意のクエリで '' findAll ''を使用できます