30. Pagination¶
Doctrine ORM ships with a Paginator for DQL queries. It
has a very simple API and implements the SPL interfaces Countable
and
IteratorAggregate
.
<?php
use Doctrine\ORM\Tools\Pagination\Paginator;
$dql = "SELECT p, c FROM BlogPost p JOIN p.comments c";
$query = $entityManager->createQuery($dql)
->setFirstResult(0)
->setMaxResults(100);
$paginator = new Paginator($query, $fetchJoinCollection = true);
$c = count($paginator);
foreach ($paginator as $post) {
echo $post->getHeadline() . "\n";
}
Paginating Doctrine queries is not as simple as you might think in the beginning. If you have complex fetch-join scenarios with one-to-many or many-to-many associations using the “default” LIMIT functionality of database vendors is not sufficient to get the correct results.
By default the pagination extension does the following steps to compute the correct result:
Perform a Count query using DISTINCT keyword.
DISTINCT キーワードを使用してカウント クエリを実行します。Perform a Limit Subquery with DISTINCT to find all ids of the entity in from on the current page.
DISTINCT で制限サブクエリを実行して、現在のページからエンティティのすべての ID を検索します。Perform a WHERE IN query to get all results for the current page.
WHERE IN クエリを実行して、現在のページのすべての結果を取得します。
This behavior is only necessary if you actually fetch join a to-many
collection. You can disable this behavior by setting the
$fetchJoinCollection
flag to false
; in that case only 2 instead of the 3 queries
described are executed. We hope to automate the detection for this in
the future.
Note
$fetchJoinCollection
flag set to true
might affect results if you use aggregations in your query.