php - 如何在 Doctrine 2 中对 native 查询进行分页?

标签 php doctrine-orm pagination dql

Doctrine 2 有 Doctrine\ORM\Tools\Pagination\Paginator 类,可用于对普通 DQL 查询进行分页。

但是,如果我向它传递 native 查询,则会出现此错误:

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 方法中从分页器类中删除类型提示,但这只会产生更多错误,因为分页器类的其他部分期望在 Query 中找到的方法不在 NativeQuery 中。

是否有任何简单的方法可以对 native 查询进行分页,而无需构建新的分页器类或将数据库中的每一行提取到数组中?

最佳答案

我制作了我自己的与 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();
    }
}

关于php - 如何在 Doctrine 2 中对 native 查询进行分页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14462836/

相关文章:

javascript - Backbone.Paginator 无限模式,带 Marionette

javascript - 在网页上加载/显示大量数据

javascript - JSON 返回重复项

php - 如何将变量传递给 codeigniter 中的条件连接?

javascript - 使用 javascript 参数选择查询

php - 为什么我的 doctrine2 实体中的对象类型在调用 persist() 和 flush() 时没有得到更新?

c# - 实体通用分页

php - 刷新页面时重复插入相同的数据

php - Symfony 软删除

php - 将 PostgreSQL DEFAULT 与 Doctrine 一起使用?