Использование разбивки на страницы в Doctrine2/Symfony2 без расширения доктрины доктрины

Я использую Doctrine2 для проекта, который может получить большой трафик, и я хочу сделать разбивку на страницы на странице поиска и получить только 5 результатов на страницу Итак, есть ли хороший способ сделать это без необходимости использования расширения доктрины и сохранения уровня абстракции ORM? Я имею в виду, что я не хочу писать какие-либо формы запросов dql и сохранять код в этом формате:

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

Ответ 1

Doctrine 2.2 поставляется с paginator. Однако для этого требуется написать DQL-запросы.

Если вы настаиваете на том, чтобы не писать DQL, вы можете начать с изучения класса Doctrine EntityRepository; в частности, метод findBy(). Он имеет необязательные параметры для ограничения и смещения, поэтому вы можете попробовать что-то вроде этого (используя ваш пример в качестве базовой линии):

$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
);

Ответ 2

Хороший вариант, который позволяет избежать написания DQL, заключается в работе с коллекциями с использованием Pagerfanta​​p >

https://github.com/whiteoctober/Pagerfanta

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

Ответ 3

В Doctrine ORM 2.3 вы также можете использовать Criteria вместе с matching в репозитории объектов. Которая теперь (начиная с версии 2.5) работает с отношениями nToMany.

Это помогает, когда ваш запрос требует другого сравнения, отличного от равного, или при разбиении на одну коллекцию OneToMany другого объекта.

$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