在symfony2.5中使用doctrine2.x我尝试按照描述设置一个paginator 在doctrine documentation
上我在文章和topten之间有一个oneToOne关系
/**
* Article
*
* @ORM\Table(name="article", indexes={@ORM\Index(name="idx_title", columns={"title"})})
* @ORM\Entity(repositoryClass="My\TestBundle\Entity\ArticleRepository")
*{
class Article
{
/**
* @var integer
*
* @ORM\Column(type="bigint", name="id")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
// ...
/**
* @ORM\OneToOne(targetEntity="My\TestMobileBundle\Entity\Topten", mappedBy="article")
*/
protected $topten;
public function __construct() {
$this->topten = new ArrayCollection();
}
}
Topten Entity:
/**
* Topten
*
* @ORM\Table(name="topten", indexes={@ORM\Index(name="article_id_idx", columns={"article_id"})})
* @ORM\Entity(repositoryClass="My\TestMobileBundle\Entity\ToptenRepository")
*
*/
class Topten
{
/**
* @var integer
*
* @ORM\Column(type="bigint", name="id")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
//...
/**
* @ORM\OneToOne(targetEntity="My\TestBundle\Entity\Article", inversedBy="topten")
* @ORM\JoinColumn(name="article_id", referencedColumnName="id", unique=true)
*/
protected $article;
}
控制器:
$dql = "SELECT a from MyTestBundle:Article a";
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery($dql)
->setFirstResult(0)
->setMaxResults(20);
$articles = new Paginator($query, $fetchJoinCollection = true);
foreach($articles as $article)
{
echo $article->getTitle() . "<br/>\n";
}
//...
Doctrine现在执行21次Mysql查询。
每当我打印标题时,它都会执行查询:
SELECT
t0.id AS id1,
//...
FROM
topten t0
WHERE
t0.article_id = ?
我做错了什么或如何阻止这种行为?
答案 0 :(得分:0)
我通过在查询中添加setHint来自行修复:
$query = $em->createQuery($dql)
->setHint(\Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD, true)
->setFirstResult(0)
->setMaxResults(20);
我通过阅读this answer here on stackoverflow找到了这个答案 似乎是学说中一对一关系的常见问题。
答案 1 :(得分:0)
这是我的分页器,对某人有用:
namespace XXX\YourBundle\Library;
/**
* @author websky
*
* Licensed MIT
* Paginator
*
* instruction:
* 1. Controller
* use XXX\YourBundle\Library\Paginator;
* new Paginator(data_array, limit, $current);
* and metods
* createPaginator()
* createPaginatorData()
*
* example:
* controller
* use XXX\YourBundle\Library\Paginator;
* $page = ($request->query->get('page') ? $request->query->get('page') : 1);
* $paginator = new Paginator($this->resultQueryArray(), 1, $page);
* return $this->render('YourBundle:Your:your.html.twig', array('list' => $paginator->createPaginator(), 'resultData' => $paginator->createPaginatorData()));
*
* 2. View - example
* {% if resultData.allElements >= 2 %}
* <section class="pagination">
* {% if resultData.first == resultData.current %}
* <a href="#" class="firstoff"></a>
* {% else %}
* <a href="{{path('your_route',{'page' : resultData.first})}}" class="first"></a>
* {% endif %}
* {% if resultData.previous == 0 %}
* <a href="#" class="prevoff"></a>
* {% else %}
* <a href="{{path('your_route',{'page' : resultData.previous})}}" class="prev"></a>
* {% endif %}
* {% for i in 1..resultData.allElements %}
* {% if resultData.allElements < 8 %}
* {% if i == resultData.current %}
* <a href="{{path('your_route',{'page' : i})}}" class="page-number active">{{ i }}</a>
* {% else %}
* <a href="{{path('your_route',{'page' : i})}}" class="page-number">{{ i }}</a>
* {% endif %}
* {% else %}
* {% if i == resultData.current %}
* <a href="{{path('your_route',{'page' : i})}}" class="page-number active">{{ i }}</a>
* {% elseif (i == (resultData.current - 3)) or (i == (resultData.current - 2)) or (i == (resultData.current - 1)) or (i == (resultData.current + 1)) or (i == (resultData.current + 2)) or (i == (resultData.current + 3)) %}
* <a href="{{path('your_route',{'page' : i})}}" class="page-number">{{ i }}</a>
* {% endif %}
* {% endif %}
*
* {% endfor %}
* of <a href="{{path('your_route',{'page' : resultData.allElements})}}" class="page-number">{{resultData.allElements}}</a>
* {% if resultData.next %}
* <a href="#{{path('your_route',{'page' : resultData.next})}}" class="next"></a>
* {% else %}
* <a href="#" class="nextoff"></a>
* {% endif %}
* {% if resultData.last == resultData.current %}
* <a href="#" class="lastoff"></a>
* {% else %}
* <a href="{{path('your_route',{'page' : resultData.last})}}" class="last"></a>
* {% endif %}
* </section>
* {% endif %}
*/
class Paginator
{
protected $limit;
protected $current;
protected $previous;
protected $next;
protected $jump;
protected $last;
protected $data;
protected $numberElements;
protected $allElements;
protected $sourceLength;
/**
* Pagination construct object
* @param array $data
* @param integer $limit
* @param integer $current
*/
public function __construct($data, $limit = 5, $current = 1)
{
$this->data = $data;
$this->limit = $limit;
$this->current = $current;
$this->sourceLength = count($data);
$this->setAllElements();
$this->setNumberElements();
}
/**
* Set limit
* @param integer $limit
* @return \XXX\YourBundle\Library\Paginator
*/
public function setLimit($limit)
{
$this->limit = $limit;
return $this;
}
/**
* Get limit
* @return integer
*/
public function getLimit()
{
return $this->limit;
}
/**
* Set current
* @param integer $current
* @return \XXX\YourBundle\Library\Paginator
*/
public function setCurrent($current)
{
$this->current = $current;
return $this;
}
/**
* Get current
* @return integer
*/
public function getCurrent()
{
return $this->current;
}
/**
* Set previous
* @param integer $previous
* @return \XXX\YourBundle\Library\Paginator
*/
public function setPrevious($previous)
{
$this->previous = $previous;
return $this;
}
/**
* Get previous
* @return integer
*/
public function getPrevious()
{
return $this->previous;
}
/**
* Set next
* @param integer $next
* @return \XXX\YourBundle\Library\Paginator
*/
public function setNext($next)
{
$this->next = $next;
return $this;
}
/**
* Get next
* @return integer
*/
public function getNext()
{
return $this->next;
}
/**
* Set last
* @param integer $last
* @return \XXX\YourBundle\Library\Paginator
*/
public function setLast($last)
{
$this->last = $last;
return $this;
}
/**
* Get last
* @return integer
*/
public function getLast()
{
return $this->last;
}
/**
* Set AllElements
* These are all elements of an array.
* @return \XXX\YourBundle\Library\Paginator
*/
public function setAllElements()
{
$this->allElements = count($this->data);
return $this;
}
/**
* Set NumberElements
* This is the number of pages for the paginator.
* @return \XXX\YourBundle\Library\Paginator
*/
public function setNumberElements()
{
$this->numberElements = ceil ($this->allElements / $this->limit);
return $this;
}
/**
* Creates an array of data to control.
* @return array
*/
public function createPaginatorData()
{
$shareArray['limit'] = $this->limit;
$shareArray['allElements'] = $this->numberElements;
$shareArray['current'] = $this->current;
$shareArray['first'] = 1;
$shareArray['previous'] = $this->current != 0 ? $this->current - 1 : false;
$shareArray['next'] = $this->current != $this->numberElements ? $this->current + 1 : false;
$shareArray['last'] = $this->numberElements;
$shareArray['sourcelength'] = $this->sourceLength;
return $shareArray;
}
/**
* Returns the elements of the page.
* @return array
*/
public function createPaginator()
{
$result = array();
for($i=(($this->current * $this->limit) - $this->limit); $i < ($this->current * $this->limit); $i++){
if(array_key_exists($i, $this->data)){
$result[] = $this->data[$i];
}
}
return $result;
}
}