2014-08-06 3 views
0

У меня есть несколько довольно сложных запросов, и для каждого из них я должен написать второй результат подсчета запросов. Так, например, в модели:Второй счетный запрос для разбивки на страницы

$dql = "SELECT u FROM AcmeBundle:Users u LEFT JOIN AcmeBundle:Products p WITH u.id = p.id"; 

Я бы создать дубликат запроса, как это:

$countingQuery = "SELECT COUNT(u.id) FROM AcmeBundle:Users u LEFT JOIN AcmeBundle:Products p WITH u.id = p.id"; 

Основная проблема в том, что при каждом изменении в первом запросе, я бы придется менять вторую.

Так что я придумал другую идею:

$countingSelect = "SELECT COUNT(u.id)"; 

$noncountingSelect = "SELECT u"; 

$dql = " FROM AcmeBundle:Users u LEFT JOIN AcmeBundle:Products p WITH u.id = p.id"; 

return $this->getEntityManager()->createQuery($noncountingSelect . $dql) 
->setHint('knp_paginator.count', $this->getEntityManager()->createQuery($countingSelect . $dql)->getSingleScalarResult()); 

Он работает, конечно, но решение кажется довольно некрасиво с большими выбирает.

Как я могу решить эту проблему?

ответ

0

Я считаю, что Doctrine \ ORM \ Tools \ Pagination \ Paginator будет делать то, что вы ищете, без дополнительной сложности.

$paginator = new Paginator($dql); 
$paginator 
    ->getQuery() 
    ->setFirstResult($pageSize * ($currentPage - 1)) // set the offset 
    ->setMaxResults($pageSize); // set the limit 

$totalItems = count($paginator); 
$pagesCount = ceil($totalItems/$paginator->getMaxResults()); 

Код выдернул из: http://showmethecode.es/php/doctrine2/doctrine2-paginator/

0

Вы можете создать хранилище клиента, как описано в the docs и добавить запрос к этому с небольшим редактировать как ..

use Doctrine\ORM\EntityRepository; 

class ProductRepository extends EntityRepository 
{ 
    public function findProducts() 
    { 
     return $this->findProductsOrCountProducts(); 
    } 

    public function findCountProducts() 
    { 
     return $this->findProductsOrCountProducts(true); 
    } 

    private function findProductsOrCountProducts($count = false) 
    { 
     $queryBuilder = $this->createQueryBuilder('u'); 

     if ($count) { 
      $queryBuilder->select('COUNT(u.id)'); 
     } 

     $query = $queryBuilder 
      ->leftJoin('AcmeBundle:Products', 'p', 'WITH', 'u.id = p.id') 
      ->getQuery() 
     ; 

     if ($count) { 
      return $query->getSingleScalarResult(); 
     } else { 
      return $query->getResult(); 
     } 
    } 
} 

Тогда вы можете позвонить ваш метод с использованием ...

$repository = $this->getDoctrine() 
    ->getRepository('AcmeBundle:Users'); 

// for products 
$products = $repository->findProducts(); 
// for count 
$countProducts = $repository->findCountProducts(); 

Примечание:

Я знаю, что это не лучшая практика, чтобы просто сказать, взглянуть на документы для бита хранилища КЛИЕНТАМ вот отображение YAML ...

# src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.yml 
Acme\StoreBundle\Entity\Product: 
    type: entity 
    repositoryClass: Acme\StoreBundle\Entity\ProductRepository 
    # ... 
Смежные вопросы