Masseleria
Masseleria

Reputation: 299

Doctrine query builder offset changeable

I'm a Symfony beginner & I'm trying to load my contact from the database using the Doctrine Query Builder as follows:

ContactRepository.php:

public function getcontactByLimit($offset, $limit)
{
    $queryBuilder = $this->_em->createQueryBuilder()
        ->select('contact')
        ->from($this->_entityName, 'contact')
        ->setFirstResult( $offset )
        ->setMaxResults( $limit )

      $query = $queryBuilder->getQuery();
      $results = $query->getResult();

    return $results;
}

DefaultController.php:

$contacts = $repository->getContactByLimit(0, 3);

Now I want to get all contacts I have in the database but just 3 by 3, what means I'm supposed to change the offset value at every loop (to 3 then 6 then 9...)

Have you any idea how to do it ?

Upvotes: 0

Views: 1929

Answers (2)

Masseleria
Masseleria

Reputation: 299

That what I did, & it works fine !

DefaultController.php:

        $offset = 0;
        $limit = 2;
        $sizeData /= $limit;

        for( $i = 0; $i < $sizeData; $i++)
        {
            $contacts = $repository->getListByLimit($offset, $limit);
            $sender->setContacts($contacts);
            $offset += $limit;
        }

ContactRepository.php:

public function getListByLimit($offset, $limit)
    {
        $queryBuilder = $this->_em->createQueryBuilder()
            ->select('contact')
            ->from($this->_entityName, 'contact')
            ->setFirstResult( $offset )
            ->setMaxResults( $limit );

        $query = $queryBuilder->getQuery();
        $results = $query->getResult();
        return $results;

Upvotes: 0

Gladhon
Gladhon

Reputation: 261

It seems for me, that you want to load objects in parts to save memory.

For that, you can use an Iterator:

  $query = $queryBuilder->getQuery();
  $iterator = $query->iterate();
  return $iterator;

And iterate in your Controller

foreach ($iterator as $row) {

}

What will happen, is that doctrine uses PDO and select your result but not read it out directly. There is a cursor on the ResultSet of the Database, which is moving on each iteration. So your PHP-Application will get each Row from Database one by one. To get 3 by 3 packages, you could use the internal position:

    $currentPackage = array();
    foreach ($iterator as $position => $row) {
        if($position % 3){
            // do here something with your 3er package before unset
            $currentPackage = array();
            $entityManager->clear(); // clear doctrine, could free memory
        }
        $currentPackage[] = $row;
    }

Upvotes: 2

Related Questions