2013-01-22 49 views
2

Doctrine 2具有Doctrine \ ORM \ Tools \ Pagination \ Paginator類,可用於對常規DQL查詢進行分頁。如何在原則2中對原生查詢進行分頁?

但是,如果我通過它本機查詢,我得到這個錯誤:

Catchable fatal error: Argument 1 passed to Doctrine\ORM\Tools\Pagination\Paginator::cloneQuery() must be an instance of Doctrine\ORM\Query, instance of Doctrine\ORM\NativeQuery given 

我試圖消除類型暗示從cloneQuery方法分頁程序類,但這恰恰提供了進一步的錯誤,因爲Paginator類的其他位需要在Query中找到的不在NativeQuery中的方法。

是否有任何簡單的方法來分頁本地查詢,而不需要建立一個新的paginator類或從數據庫中提取每一行到數組?

+0

我不認爲有這樣的事 - 至少我還沒有找到任何東西。 –

回答

6

我做了我自己的paginator適配器類與Zend_Paginator兼容。

可能不會是最靈活的,因爲它依賴於查詢開始附近有一個「FROM」(請參閱​​count()方法),但它是一個相對快速和簡單的修復方法。

/** 
* Paginate native doctrine 2 queries 
*/ 
class NativePaginator implements Zend_Paginator_Adapter_Interface 
{ 
    /** 
    * @var Doctrine\ORM\NativeQuery 
    */ 
    protected $query; 
    protected $count; 

    /** 
    * @param Doctrine\ORM\NativeQuery $query 
    */ 
    public function __construct($query) 
    { 
     $this->query = $query; 
    } 

    /** 
    * Returns the total number of rows in the result set. 
    * 
    * @return integer 
    */ 
    public function count() 
    { 
     if(!$this->count) 
     { 
      //change to a count query by changing the bit before the FROM 
      $sql = explode(' FROM ', $this->query->getSql()); 
      $sql[0] = 'SELECT COUNT(*)'; 
      $sql = implode(' FROM ', $sql); 

      $db = $this->query->getEntityManager()->getConnection(); 
      $this->count = (int) $db->fetchColumn($sql, $this->query->getParameters()); 
     } 

     return $this->count; 
    } 

    /** 
    * Returns an collection of items for a page. 
    * 
    * @param integer $offset Page offset 
    * @param integer $itemCountPerPage Number of items per page 
    * @return array 
    */ 
    public function getItems($offset, $itemCountPerPage) 
    { 
     $cloneQuery = clone $this->query; 
     $cloneQuery->setParameters($this->query->getParameters(), $this->query->getParameterTypes()); 

     foreach($this->query->getHints() as $name => $value) 
     { 
      $cloneQuery->setHint($name, $value); 
     } 

     //add on limit and offset 
     $sql = $cloneQuery->getSQL(); 
     $sql .= " LIMIT $itemCountPerPage OFFSET $offset"; 
     $cloneQuery->setSQL($sql); 

     return $cloneQuery->getResult(); 
    } 
} 
+2

我不確定paginator是如何實現的,但是在不轉義的情況下直接將參數傳遞給SQL時,要小心SQLi。在這種情況下投射到int就足夠了 –

+0

我認爲這不適用於連接.. – fiorebat

0

如果你有DBAL查詢構建器(您已與 $ yourDbalQueryBuilder = $連接 - > createQueryBuilder()構成; ),則可以使用:

$ yourDbalQueryBuilder-> setFirstResult(0 ) - > setMaxResults(100000000) - >執行() - > rowCount時();