Doctrine2 large collections

2020-07-13 07:46发布

问题:

I have been playing with doctrine2 + ZF setup for the last couple of days.

One of the things I still can't figure out is the large array collection assosicaitons. For example let's say we have an entity called Post and each post can have many comments.

<?php
/**
 * @Entity
*/
class Post
{
  /**
   * @OneToMany(targetEntity="Comment", mappedBy="post")
   */
   protected $comments;
}
?>

Now this will load all comments if I do

$post->comments

But what if there are, say 10000 comments for this particular post? Then all will be loaded which is not good. And as far as I know slice/pagination will not be available until doctrine 2.1.

Can someone advice me how I can paginate comments? With DQL maybe? if DQL, where do you implement this?Do I create a getComments method in the Post entity and do the DQL there?

Thanks Bill

回答1:

I'm using pagination from https://github.com/beberlei/DoctrineExtensions, it works great, at least for me.

Edit: Not sure this will help you, but here's how I did my pagination

Controller

// Create the query
$qb = $this->_em->createQueryBuilder();

$qb->select('p')
   ->from('Identiti_Entities_Pengguna', 'p');

// Sorting
$qb->addOrderBy('p.' . $input->sort, $input->dir);

$q = $qb->getQuery();

// Pagination
$itemPerPage = 100;

$records = new Zend_Paginator(
                new DoctrineExtensions\Paginate\PaginationAdapter($q));

$records->setCurrentPageNumber($input->page)
        ->setItemCountPerPage($itemPerPage)
        ->setPageRange(10);

$this->view->records = $records;

View

<?
echo $this->paginationControl($this->records,
                              'Sliding',
                              'partials/pagination.phtml');
?>

pagination.html

<?php if ($this->pageCount): ?>
<ul id="pagination-digg">
    <li class="previous"><a href="#">Pages: <?=$this->pageCount?></a></li>
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
  <li class="previous"><a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
    &lt; Previous
  </a></li>
<?php else: ?>
    <li class="previous-off">&lt; Previous</li>
<?php endif; ?>


<!-- Numbered page links -->
<?php foreach ($this->pagesInRange as $page): ?>
    <?php if ($page != $this->current): ?>
        <li>
            <a href="<?php echo $this->url(array('page' => $page)); ?>">
                <?php echo $page; ?>
            </a>
        </li>
    <?php else: ?>
        <li class="active"><?php echo $page; ?></li>
    <?php endif; ?>
<?php endforeach; ?>

<!-- Next page link -->
<?php if (isset($this->next)): ?>
    <li class="next">
        <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
            Next &gt;
        </a>
    </li>
<?php else: ?>
  <li class="next-off">Next &gt;</li>
<?php endif; ?>
</ul>
<?php endif; ?>


回答2:

You may consider implementing Zend_Paginator_Adapter_Interface.

See ZF docs for more details:

  • Zend Framework: Documentation: Advanced usage - Zend Framework Manual


回答3:

Doctrine 2.2 now has a Paginator class. See this link for how to use it with Zend_Framework: Reply to How to use D2's Paginator with Zend_Paginator