Symfony2 QueryBuilder加入ON和WITH区别

时间:2013-07-02 09:58:14

标签: symfony doctrine-orm left-join query-builder

我是Symfony2的新手,我通过QueryBuilder和Doctrine 2成功构建了我的第一个连接。 可能这是一个愚蠢的问题但是在线和Symfony2的方法中我都无法找到任何理解连接子句“WITH”和“ON”之间的区别。

例如,这是我的加入代码:

->leftJoin('EcommerceProductBundle:ProductData', 'pdata', 'WITH', 'prod.id = IDENTITY(pdata.product)')

效果很好,但如果我将ON代替WITH,我会收到以下错误:

  

[语法错误]第0行,第200行:错误:预期   Doctrine \ ORM \ Query \ Lexer :: T_WITH,“开启”

为什么呢?我在对象中看到T_ON和T_WITH都有join子句,但是它们的使用区别是什么?它们的用途是什么?

2 个答案:

答案 0 :(得分:48)

@florian给了你正确答案,但让我试着在例子上解释一下:

在sql中,连接是这样完成的:

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id

(或类似的东西)

现在在Doctrine中,您不需要使用ON子句,因为doctrine知道您实体中的关系注释。所以上面的例子是:

// CategoryRepository.php
public function getCategoriesAndJoinProducts() 
{
    return $this->createQueryBuilder("o")
        ->leftJoin("o.products", "p")->addSelect("p") 
        ->getQuery()->getResult() ;
}

两者都会获取所有类别并加入与之关联的产品。

现在出现WITH子句。如果您只想加入价格大于50的产品,您可以在SQL中执行此操作:

SELECT * FROM category
    LEFT JOIN product ON product.category_id = category.id AND product.price>50

在学说中:

// CategoryRepository.php
public function getCategoriesAndJoinProductsWithPriceBiggerThan($price) 
{
    return $this->createQueryBuilder("o")
        ->leftJoin("o.products", "p", "WITH", "p.price>:price")
            ->setParameter("price", price)->addSelect("p") 
        ->getQuery()->getResult() ;
}

所以,实际上如果你使用的是Doctrine,你永远不应该使用ON。如果你需要这样的东西,你几乎可以肯定你搞砸了别的东西。

答案 1 :(得分:6)

理论上,ON允许您提供完整的连接标准,而WITH允许在默认值(IMHO)中添加其他标准。

但是,DQL允许的是避免给出JOIN标准:

您只需说:$qb->leftJoin('prod.pdata', 'pdata');

doctrine2将正确处理连接。

以下是与此相关的问题:Can I use "ON" keyword in DQL or do I need to use Native Query?