2012-03-06 3 views
11

Używam Doctrine2 do projektu, który może generować duży ruch i chcę zrobić kilka stronicowania na stronie wyszukiwania i pobrać tylko 5 wyników na stronę Czy istnieje dobry sposób robienia tego bez potrzeby używania rozszerzenia doktryny i utrzymywania warstwy abstrakcji ORM? To znaczy nie chcę pisać dowolną formę zapytań DQL i strzec mojego kodu w tym formacie:Używanie stronicowania w Doctrine2/Symfony2 bez rozszerzenia paginatora Doctrine

$repo= $this->getDoctrine() 
        ->getEntityManager() 
        ->getRepository('AcmeOfficeBundle:Project'); 
     $list=$repo->findBy(array('PROJ_private' => "0")); 

Odpowiedz

35

Doctrine 2.2 ships with a paginator. Jednak wymaga ono od Ciebie pisania zapytań DQL.

Jeśli nalegasz na nie pisanie żadnego DQL, możesz zacząć od spojrzenia na klasę Doctrine EntityRepository; konkretnie, the findBy() method. Posiada opcjonalne parametry limitu i offsetu, więc można spróbować coś takiego (przy użyciu przykład jako punkt odniesienia):

$num_pages = x; // some calculation of what page you're currently on 
$repo = $this->getDoctrine() 
       ->getRepository('AcmeOfficeBundle:Project'); 
$list = $repo->findBy(
    array('PROJ_private' => "0"), //search criteria, as usual 
    array(/* orderBy criteria if needed, else empty array */), 
    5, // limit 
    5 * ($num_pages - 1) // offset 
); 
+1

Thx za część doktryny 2.2 wysyłce z paginator, nie wiedziałem o tym. – Matt

+2

Jak mogę uzyskać całkowitą liczbę stron dla zestawu wyników? Czy muszę uruchomić oddzielną funkcję findBy() bez dwóch ostatnich parametrów, aby uzyskać całkowitą liczbę wyników, a następnie samemu ją obliczyć? Wydaje się to nieskuteczne, ale nie jestem pewien, czy jest to bardziej elegancki sposób na zrobienie tego. – imkingdavid

0

Dobrym rozwiązaniem, które pozwala uniknąć pisania DQL jest do działania na zbiorach wykorzystujących Pagerfanta

https://github.com/whiteoctober/Pagerfanta

use Pagerfanta\Adapter\DoctrineCollectionAdapter; 
$user = $em->find("App\DoctrineORM\User", 1); 
$adapter = new DoctrineCollectionAdapter($user->getGroups()); 
0

w doktrynie ORM 2.3 można również wykorzystać Criteria wraz z matching na repozytorium podmiotu. Który teraz (od wersji 2.5) działa z wieloma relacjami.

Pomaga to, gdy zapytanie wymaga innego porównania, innego niż równe lub podczas dzielenia stron na kolekcję OneToMany innego obiektu.

$page = (isset($_GET['page']) && $_GET['page'] > 0 ? $_GET['page'] : 1); 
$limit = 20; 
$offset = ($limit * ($page - 1)); 
$criteria = \Doctrine\Common\Collections\Criteria::create() 
    ->setMaxResults($limit) 
    ->setFirstResult($offset); 
$expr = $criteria->expr(); 
$user = $em->getRepository('AcmeOfficeBundle:Project') 
    ->matching($criteria->where($expr->gt('PROJ_private', 0))); 
$total_records = $user->count(); 

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#filtering-collections