Использование разбивки на страницы в 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, заключается в работе с коллекциями с использованием Pagerfantap >
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