【问题标题】:doctrine 2 and zend paginator教义2和zend分页器
【发布时间】:2011-07-09 14:01:01
【问题描述】:

我想在 zend_paginator 中使用学说

这里有一些示例查询:

$allArticleObj = $this->_em->getRepository('Articles'); $qb = $this->_em->createQueryBuilder();

    $qb->add('select', 'a')
            ->add('from', 'Articles a')
            ->setFirstResult(0)
            ->setMaxResults(5);

是否有任何示例代码显示我们可以为教义 2 查询构建器编写一个 zend_paginator 适配器?

【问题讨论】:

    标签: php zend-framework doctrine-orm pagination zend-paginator


    【解决方案1】:

    您不需要实现 Zend_Paginator_Adapter_InterfaceZend_Paginator_Adapter_Iterator 已经实现了它。

    您可以简单地将 Doctrine 的 Paginator 传递给 Zend_Paginator_Adapter_Iterator,然后将其传递给 Zend_Paginator。然后调用 Zend_Paginator::setItemCountPerPage($perPage)Zend_Paginator::setCurrentPageNumber($current_page)。像这样:

    use Doctrine\ORM\Tools\Pagination as Paginator; // goes at top of file
    
    SomeController::someAction() 
    {
     $dql = "SELECT s, c FROM Square\Entity\StampItem s JOIN s.country c ".' ORDER BY '.  $orderBy . ' ' . $dir;
     
     $query = $this->getEntityManager()->createQuery($dql);
     $d2_paginator = new Paginator($query); \\
     
     $d2_paginator_iter = $d2_paginator->getIterator(); // returns \ArrayIterator object
     
     $adapter =  new \Zend_Paginator_Adapter_Iterator($d2_paginator_iter);
      
     $zend_paginator = new \Zend_Paginator($adapter);          
                           
     $zend_paginator->setItemCountPerPage($perPage)
                ->setCurrentPageNumber($current_page);
    
     $this->view->paginator = $zend_paginator; //Then in your view, use it just like your currently use     
    }
     
    

    然后你像往常一样在视图脚本中使用分页器。

    解释:

    Zend_Paginator 的构造函数可以采用 Zend_Paginator_Adapter_Interface,由 Zend_Paginator_Adpater_Iterator 实现。现在,Zend_Paginator_Adapter_Iterator 的构造函数采用 \Iterator 接口。这个 \Iterator 还必须实现 \Countable(您可以通过查看 Zend_Paginator_Adapter_Iterator 的构造函数看到)。由于 Paginator::getIterator() 方法返回一个 \ArrayIterator,因此根据定义它符合要求(因为 \ArrayIterator 实现了两个 \Iterator\Countable)。

    请参阅从 Doctrine 1 到 Doctrine 的“Zend 框架:初学者指南”代码从 Doctrine 1 到 Doctrine 2 的移植:https://github.com/kkruecke/zf-beginners-doctrine2。它包括使用 Zend_Paginator_Adapter_Iterator 和 Doctrine 2' Doctrine\ORM\Tools\Pagination\PaginatorZend_Paginator 分页代码。

    代码在这里(虽然它可能不适用于最新的 DoctrineORM 2.2)但示例是有效的:https://github.com/kkruecke/zf-beginners-doctrine2/tree/master/ch7

    【讨论】:

    • 那个实现不正确。即使它有点工作,当您运行 $d2_paginator->getIterator() 时,它会从数据库中检索所有实体,然后 Zend paginator 只是将其过滤掉。所以如果你有很多记录需要分页,这种方法会很慢。
    • 同意。这对我来说最终是 502,因为脚本花费的时间太长。这也仅适用于约 20K 记录。不可扩展。
    【解决方案2】:

    我很惊讶要找到一个不会导致 Doctrine 2 和 ZF1 的大型集合出现性能问题的适配器示例。

    我的灵魂确实使用了the Doctrine\ORM\Tools\Pagination\Paginator from Doctrine 2.2,就像@Kurt 的回答一样;但是不同之处在于这将返回来自getItems 的教义分页器(它本身就是\Iterator),而不会对整个查询结果进行水合。

    use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
    use Doctrine\ORM\Query;
    
    class DoctrinePaginatorAdapter implements \Zend_Paginator_Adapter_Interface
    {
        protected $query;
    
        public function __construct(Query $query)
        {
            $this->query = $query;
        }
    
        public function count()
        {
            return $this->createDoctrinePaginator($this->query)->count();
        }
    
        public function getItems($offset, $itemCountPerPage)
        {
            $this->query->setFirstResult($offset)
                        ->setMaxResults($itemCountPerPage);
    
            return $this->createDoctrinePaginator($this->query);
        }
    
        protected function createDoctrinePaginator(Query $query, $isFetchJoinQuery = true)
        {
            return new DoctrinePaginator($query, $isFetchJoinQuery);
        }
    
    } 
    

    【讨论】:

      【解决方案3】:

      当然,结果是你必须实现Zend_Paginator_Adapter_Interface,这实质上意味着实现这两种方法:

      count()

      getItems($offset, $perPage)

      您的适配器将接受 Doctrine 查询作为构造函数参数。

      原则上,getItems() 部分实际上很简单。只需将$offset$perPage 限制添加到查询中(就像您在示例中所做的那样)并执行查询。

      在实践中,count() 业务往往比较棘手。我会按照Zend_Paginator_Adapter_DbSelect 的示例,将Zend_Db 操作替换为Doctrine 类似物。

      【讨论】:

        【解决方案4】:

        请更改

        use Doctrine\ORM\Tools\Pagination as Paginator;
        

        use Doctrine\ORM\Tools\Pagination\Paginator as Paginator;
        

        【讨论】:

          猜你喜欢
          • 2014-09-10
          • 1970-01-01
          • 2011-09-25
          • 1970-01-01
          • 1970-01-01
          • 2013-04-18
          • 1970-01-01
          • 2012-12-08
          • 1970-01-01
          相关资源
          最近更新 更多