Doctrine 2 Pagination with Association Mapping

2019-05-11 17:45发布

问题:

I am wondering how can you paginate the results obtained from an entity association mapping in Doctrine 2? For example

class Customer {
  /**
   * @OneToMany(targetEntity="Order")
   */
  private $orders;
}

can be used as such:

$customer->getOrders();

which will return a collection of Order objects.

The problem is when there are a large number of order objects.

We can use Doctrine\ORM\Tools\Pagination\Paginator when building custom queries, however I do not see any way to hook into query generation when utilising association mapping.

class Paginator {
  /** 
   * @param Query|QueryBuilder $query A Doctrine ORM query or query builder. 
   */
  function __construct(
    //....

回答1:

If you use the EXTRA_LAZY fetch mode, Doctrine will not retrieve all objects when hydrating the collection. It will only retrieve the subset needed when you use the slice() method on the collection.

class Customer {
    /**
     * @OneToMany(targetEntity="Order", fetch="EXTRA_LAZY")
     */
    private $orders;
}

$cust = new Customer;
$orders = $cust->getOrders()->slice(100, 50);

You would need to verify how this interacts with the pagination.



回答2:

Collections have a filtering API that allows to slice parts of data from a collection. If the collection has not been loaded from the database yet, the filtering API can work on the SQL level to make optimized access to large collections. Doctrine Filtering Collections

class Customer {
  /**
   * @OneToMany(targetEntity="Order")
   */
  private $orders;

  public function getOrders($offset = 0, $limit = 30){

    $criteria = Criteria::create()
                ->setFirstResult($offset)
                ->setMaxResults($limit);

    return $this->orders->matching($criteria);

  }

}

$cust = new Customer;
$orders = $cust->getOrders(50, 100);