Doctrine 2有Doctrine \ ORM \ Tools \ Pagination \ Paginator类,可以用来对普通的DQL查询进行分页。
但是,如果我将原始查询传递给它,我会收到此错误:
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类中删除类型提示,但这只会产生更多错误,因为paginator类的其他位需要在Query中找到不在NativeQuery中的方法。
有没有简单的方法来分页本机查询而无需构建新的paginator类或从数据库中将每一行都提取到数组中?
答案 0 :(得分:8)
我使自己的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();
}
}
答案 1 :(得分:0)
如果你有一个dbal查询构建器(你已经构建了 $ yourDbalQueryBuilder = $ connection-> createQueryBuilder(); )然后你可以使用:
$ yourDbalQueryBuilder-> setFirstResult(0) - > setMaxResults(100000000) - >执行() - > rowCount时();
答案 2 :(得分:0)
public function countTotalRecords($query, string $primaryKey = '*'): int
{
if ($query instanceof QueryBuilder) {
$paginator = new Paginator($query->getQuery());
return count($paginator);
} else if ($query instanceof NativeQuery) {
$rsm = new ResultSetMappingBuilder($query->getEntityManager());
$rsm->addScalarResult('count', 'count');
$sqlCount = "select count(".$primaryKey.") as count from (" . $query->getSQL() . ") as item";
$count = $query->getEntityManager()->createNativeQuery($sqlCount, $rsm);
if ($query->getParameter('limit')) {
$query->setParameter('limit', null);
}
$count->setParameters($query->getParameters());
return (int)$count->getSingleScalarResult();
}
return 0;
}