129

我一直在阅读 Doctrine 的文档,但我一直无法找到对 findAll() 结果进行排序的方法。

我正在使用 symfony2 + 学说,这是我在控制器中使用的语句:

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

但我希望按用户名升序排列结果。

我一直在尝试以这种方式将数组作为参数传递:

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

但它不起作用(它也不抱怨)。

有没有办法在不构建 DQL 查询的情况下做到这一点?

4

12 回答 12

247

As @Lighthart as shown, yes it's possible, although it adds significant fat to the controller and isn't DRY.

You should really define your own query in the entity repository, it's simple and best practice.

use Doctrine\ORM\EntityRepository;

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

Then you must tell your entity to look for queries in the repository:

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

Finally, in your controller:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findAll();
于 2013-06-15T04:09:12.753 回答
89
$this->getDoctrine()->getRepository('MyBundle:MyTable')->findBy([], ['username' => 'ASC']);
于 2014-09-02T10:18:51.023 回答
26

简单的:

$this->getDoctrine()->getRepository('AcmeBundle:User')->findBy(
    array(),
    array('username' => 'ASC')
);
于 2017-04-04T09:58:48.050 回答
22

有时查看源代码很有用。

例如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)
于 2015-11-12T10:03:49.840 回答
7

这对我有用:

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

保持第一个数组为空会取回所有数据,这在我的情况下有效。

于 2015-02-25T14:55:32.887 回答
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,
        ]);
    }
}
于 2013-06-14T20:47:47.420 回答
5

Symfony 中的 findBy 方法除了两个参数。第一个是您要搜索的字段数组,第二个数组是排序字段及其顺序

public function findSorted()
    {
        return $this->findBy(['name'=>'Jhon'], ['date'=>'DESC']);
    }
于 2018-11-20T08:30:46.113 回答
5

查看 Doctrine API 源代码:

class EntityRepository{
  ...
  public function findAll(){
    return $this->findBy(array());
  }
  ...
}
于 2016-03-02T12:24:07.027 回答
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() 方法。

于 2013-06-15T12:10:33.707 回答
2

尝试这个:

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

$entities = $em->getRepository('MyBundle:MyTable')->findBy(array(), array('username' => 'ASC'));
于 2015-06-24T18:57:40.937 回答
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子句更快,而且没有迭代器的开销。

于 2014-12-30T11:53:26.603 回答
1

像这样修改 EntityRepository 中的默认 findAll 函数:

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

这样,您可以在任何数据表的任何查询中使用“findAll”,并带有对查询进行排序的选项

于 2018-03-27T12:54:56.263 回答