我是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子句,但是它们的使用区别是什么?它们的用途是什么?
答案 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?