[英]How to use pagination with JOINs in Zend Framework 2?
In an application I implemented a Mapper
to retrieve data from the database and objects from the ResultSet
. 在一个应用程序中,我实现了一个Mapper
来从数据库中检索数据并从ResultSet
检索对象。 In order to get all the data I have to JOIN
multiple tables. 为了获得所有数据,我必须JOIN
多个表。 Then I get a huge array structured like this: 然后,我得到一个巨大的数组,其结构如下:
[
0 => [
main_id => 1,
main_title => 'lorem',
main_desc => 'ipsum',
foo_id => '12',
foo_name => 'qwer',
bar_id => '56',
bar_name => 'asdf'
],
1 => [
main_id => 1,
main_title => 'lorem',
main_desc => 'ipsum',
foo_id => '12',
foo_name => 'qwer',
bar_id => '67',
bar_name => 'hjkl'
],
2 => [
main_id => 1,
main_title => 'lorem',
main_desc => 'ipsum',
foo_id => '23',
foo_name => 'uiop',
bar_id => '67',
bar_name => 'hjkl'
],
...
10 => [
main_id => 1,
main_title => 'lorem',
main_desc => 'ipsum',
foo_id => '23',
foo_name => 'uiop',
bar_id => '91',
bar_name => 'cvbn'
],
11 => [
main_id => 2,
main_title => 'dolor',
main_desc => 'sit',
foo_id => '78',
foo_name => 'fghj',
bar_id => '89',
bar_name => 'vbnm'
],
...
12 => [
main_id => 3,
foo_id => '135',
bar_id => '246',
...
],
13 => [
main_id => 3,
foo_id => '135',
bar_id => '468',
...
],
14 => [
main_id => 3,
foo_id => '357',
bar_id => '680',
...
],
...
1000 => [
...
]
]
Then I iterate over the array, build objects ( Main
, Foo
, Bar
etc.), and combine them, eg 然后,我遍历数组,构建对象( Main
, Foo
, Bar
等),并将它们组合起来,例如
$newMain = $myMainHydrator->hydrate($results[0]);
$newFoo = $myFooHydrator->hydrate($results[0]);
$newBar = $myBarHydrator->hydrate($results[0]);
$newFoo->setBar($newBar);
$newMain->setFoo($newFoo);
$resultObjects[] = $newMain;
Now I built in a Paginator
and got following issue: The Paginator
sets a LIMIT
, eg 10
, and retrieves then only 10
rows, while I need for every object more than one result row (currently even 12
rows). 现在,我内置了一个Paginator
并遇到以下问题: Paginator
设置一个LIMIT
(例如10
,然后仅检索10
行,而每个对象都需要一个以上的结果行(目前甚至需要12
行)。
I cannot believe, that the Paginator
cannot handle JOIN
s, so there must be a way to get it working. 我不敢相信, Paginator
无法处理JOIN
,因此必须有一种使它起作用的方法。 How to use the Paginator
for complex SELECT
s with JOIN
s? 如何将Paginator
用于带有JOIN
的复杂SELECT
?
The issue can be solved by replacing of the LIMIT
clause by an IN
in the Paginator
Adapter
's getItems(...)
. 可以通过在Paginator
Adapter
的getItems(...)
Paginator
IN
替换LIMIT
子句来解决此问题。
namespace Foo\Paginator\Adapter;
use Zend\Db\Sql\Select;
use Zend\Paginator\Adapter\DbSelect;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Expression;
class FooPaginatorAdapter extends DbSelect
{
public function count()
{
$select = new Select();
$select->from('foo')->columns([self::ROW_COUNT_COLUMN_NAME => new Expression('COUNT(*)')]);
$statement = $this->sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
$row = $result->current();
$this->rowCount = $row[self::ROW_COUNT_COLUMN_NAME];
return $this->rowCount;
}
public function getItems($offset, $itemCountPerPage)
{
$select = clone $this->select;
// replaced
// $select->offset($offset);
// $select->limit($itemCountPerPage);
// by this
$relevantIds = $this->getRelevantIds($offset, $itemCountPerPage);
$select->where->in('foo.id', $relevantIds);
$statement = $this->sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
$resultSet = clone $this->resultSetPrototype;
$resultSet->initialize($result);
return iterator_to_array($resultSet);
}
protected function getRelevantIds($offset, $itemCountPerPage)
{
$sql = new Sql($this->sql->getAdapter());
$select = $sql->select('foo');
$select->columns(['id']);
$select->offset($offset);
$select->limit($itemCountPerPage);
$statement = $this->sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
$resultArray = iterator_to_array($result);
$relevantIds = array_column($resultArray, 'id');
return $relevantIds;
}
}
As you see in this case the ID
s first have to be retrieved with a separate database request. 如您所见,在这种情况下,首先必须使用单独的数据库请求来检索ID
。 But anyway -- it works. 但是无论如何-它起作用。 If you know a better solution, please feel free to post it. 如果您知道更好的解决方案,请随时发布。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.