如何从doctrine查询生成器获取部分结果

时间:2013-06-07 23:58:07

标签: php sql symfony doctrine query-builder

我有一个产品实体,其中有一个数组作为属性:

     /**
     * @ORM\OneToMany(targetEntity="Shopious\MainBundle\Entity\ProductPicture", mappedBy="product", cascade={"persist","remove"})
     */
    protected $pictures;

    /** 
    * @Accessor(getter="getCover") 
    */
    private $cover;
    public function getCover()
    {
        if($this->pictures->count() > 0) {
            return $this->pictures[0];
        }
        return new ProductPicture();
    }

现在在我的查询构建器中,我有以下代码:

 $query = $em->createQueryBuilder()->select('p')
            ->from("SiteMainBundle:Product", 'p')
            ->innerJoin('p.category', 'c')
            ->innerJoin('p.shop', 'shop')
            ;

这里的问题是我不想选择p的所有属性。所以我只想在图片数组中获得第一个ProductPicture(在我的情况下,它类似于getCover()方法)。我该怎么做?

到目前为止,我可以过滤掉我想要的部分属性:

 $query = $em->createQueryBuilder()->select('p.name, p.id')
                ->from("SiteMainBundle:Product", 'p')
                ->innerJoin('p.category', 'c')
                ->innerJoin('p.shop', 'shop')
                ->innerJoin('p.pictures', 'pictures')
                ;

所以在上面的例子中我已经完成了内部联接的图片,但是如何从这里获得第一个元素?

总之,我的问题是如何使用查询构建器选择/查询图片数组中的第一个ProductPicture?因为当我这样做时:

$ query = $ em-> createQueryBuilder() - > select('p')

它返回整个产品属性,但我不想要整个产品属性..我只想要其中的一些,例如id,name等。但是其中一个产品属性实际上是一个实体(其中是ProductPicture),那么如何在select语句中返回它?

修改

这是一个关于如何将图片内部连接起来的SQL等价物:

SELECT * 
FROM  `product` 
JOIN  `product_picture` ON  `product`.id =  `product_picture`.product_id
WHERE  `product`.id =100
LIMIT 1

2 个答案:

答案 0 :(得分:2)

尝试类似这样的事情,如果它是一对多的,正常的mySQL行为会返回带有冗余产品数据的几条记录,如果在这里发生相同的情况,那么只返回第一条记录才能做到这一点。

PS 假设ProductPicture实体具有您想要获取的网址属性

$query = $em->createQueryBuilder()->select('p.id, p.name, pictures.url')
            ->from("SiteMainBundle:Product", 'p')
            ->innerJoin('p.category', 'c')
            ->innerJoin('p.shop', 'shop')
            ->innerJoin('p.pictures', 'pictures')
            ;

答案 1 :(得分:0)

为您的实体添加带有DQL的自定义存储库方法,然后从控制器中调用它

您可以根据需要为存储库方法命名,对于此示例,我使用的是findProductWithPicture

class ProductRepository extends EntityRepository
{
    /**
     * @param integer $id
     */
    public function findProductWithPicture($id)
    {
        $dql = <<<SQL
SELECT
    p.id    id,
    p.name  name,
    q       picture
FROM
    Shopious\MainBundle\Entity\ProductPicture q,
    Shopious\MainBundle\Entity\Product p
WHERE
    p.id        = :picture_id  AND
    q.product   = p.id
SQL;

        $query = $this->_em->createQuery($dql)->setParameter('picture_id', $id);

        return $query->setMaxResults(1)->getResult();
    }
}

从控制器中使用它

$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('ShopiousMainBundle:Product')->findProductWithPicture($id);

return $this->render('ShopiousMainBundle:Product:show.html.twig', array(
    'product' => $product[0]
));

在渲染的Twig模板中,您可以像这样访问它们

<p>{{ product.id }}
<p>{{ product.name }}
<p>{{ product.picture.whatever_property }}