FindAll Doctrine yöntemi nasıl sıralanır


111

Doctrine'in belgelerini okuyordum, ancak findAll () Sonuçlarını sıralamanın bir yolunu bulamadım.

Symfony2 + doktrini kullanıyorum, bu benim Kontrolcümün içinde kullandığım ifade:

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

ancak sonuçların artan kullanıcı adlarına göre sıralanmasını istiyorum.

Şu şekilde bir argüman olarak bir dizi geçirmeye çalışıyorum:

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

ama işe yaramıyor (o da şikayet etmiyor).

Bunu bir DQL sorgusu oluşturmadan yapmanın bir yolu var mı?

Yanıtlar:


229

@Lighthart'ın gösterildiği gibi, kontrol cihazına önemli miktarda yağ eklemesine ve KURU olmamasına rağmen evet mümkündür.

Varlık havuzunda gerçekten kendi sorgunuzu tanımlamalısınız, bu basit ve en iyi uygulamadır.

use Doctrine\ORM\EntityRepository;

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

Daha sonra, varlığınıza arşivdeki sorguları aramasını söylemelisiniz:

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

Son olarak, kontrol cihazınızda:

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

2
Bu benimkinden daha iyi bir yaklaşım, ancak dql yazacaksınız; benim metodumda daha az dql var ve bu yüzden OP'nin kısıtlamasına cevap veriyor. Açıkçası, dql korkusunun üstesinden gelinmesi gerekir. Mümkünse benim için bu yöntemi tercih edin.
Lighthart

bu dql korkusu değil ve bu cevabı okumadan önce sonuçta bunu başarmak için DQL kullandım, ancak başlangıçta DQL kullanmak istemedim çünkü denetleyicimde herhangi bir DQL yoktu ve buna bağlı kalmak istedim. denetleyicinin sahip olduğu kod stili. Bu çözümler benim için gerçekten iyi çalışıyor!
ILikeTacos

1
Veya basitçe: $ this-> getDoctrine () -> getRepository ('AcmeBundle: Kullanıcı') -> findBy (array (), array ('username' => 'ASC'));
Benji_X80

1
@ Benji_X80 Bu tek astar kesinlikle daha kısa olsa da, hiç KURU değil. FindAll yöntemi, denetleyiciye değil depoya aittir.
Pier-Luc Gendreau

1
Varlığa, yorumları kullanmaktan başka bir yolla özel depodaki sorguları aramasını söyleyebilir misiniz? Bu şimdiye kadar gördüğüm en korkunç programlama uygulaması
Sejanus

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

24

Basit:

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

Bu harika çalıştı! Symfony 4 ile de tam olarak bu şekilde çalışıyor
Robert Saylor

20

Bazen kaynak koduna bakmak faydalıdır.

Örneğin findAlluygulama çok basittir ( vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php):

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

Bu yüzden bakar findByve ihtiyacımız olanı buluruz ( orderBy)

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

6

Bu benim için çalışıyor:

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

İlk diziyi boş tutmak tüm verileri geri getirir, benim durumumda işe yaradı.


5

Doctrine API kaynak koduna bakın:

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

Bu kod parçası hiçbir şeyi sıralamaz
Nico Haase

5

Bir kriter kullanmanız gerekir, örneğin:

<?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'deki findBy yöntemi iki parametreyi hariç tutar. Birincisi, aramak istediğiniz alan dizisidir ve ikinci dizi, sıralama alanı ve sırasıdır.

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

Kısa cevabınıza bir açıklama ekleyebilir misiniz?
Nico Haase

Bu çok kısa bir cevap. Ayrıntılı - açıklayın ... düzenleyin .
Paul Hodges

bu mükemmel cevaptı! findBy (array (), array ('fieldname' => 'ASC') Bu, hepsini bulacak ve belirtilen yönde alanda sıralayacaktır.
Robert Saylor

2

Bir dizi yineleyici kullanarak mevcut bir ArrayCollection'ı sıralayabilirsiniz.

$ collection'ın findAll () tarafından döndürülen ArrayCollection olduğunu varsayarsak

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

Bu, findAllOrderBy () yöntemini oluşturmak için kolayca deponuza yerleştirebileceğiniz bir işleve dönüştürülebilir.


4
Burada amacın ne? Bunun için gereğinden fazla kullanım durumu vardır ... yani PHP'de önceden getirilmiş bir koleksiyonu sıralamak, sırf sıralama için başka bir mysql sorgusu yapmaktan her zaman daha hızlıdır! Aynı toplama verilerini bir sayfada iki farklı sıralama stilinde çıkarmanız gerektiğini düşünün ...
Nicolai Fröhlich

2
Genel olarak, sıralı bir sorguyu döndürmek, veritabanının işi olmalıdır. OTOH, bu tekniğin bahsettiği daha fazla ilgili vakalara uygulanabilirliği var.
Lighthart

2

Bunu dene:

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

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

1

Ben nifr yazan çözüme bir alternatif kullanıyorum.

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

ORDER BY yan tümcesinden daha hızlıdır ve Yineleyicinin ek yükü yoktur.


Lütfen cevabınıza biraz daha açıklama ekleyin. Uygulamanızda sıralama, veritabanı düzeyinde yapmaktan nasıl daha hızlı olabilir?
Nico Haase

0

EntityRepository'deki varsayılan findAll işlevini şu şekilde değiştirin:

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

Bu şekilde, herhangi bir veri tablosu için herhangi bir sorguda, sorguyu sıralama seçeneğiyle birlikte "findAll" öğesini kullanabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.