我尝试编写这种查询:
$qb = $this
->createQueryBuilder()
->select('gh')
->orderBy("IF(gh.language = 'en', 1, 0)", 'desc')
->getQuery();
它如何运作?
答案 0 :(得分:2)
简短的回答:你不能。
答案很长:
Doctrine仅支持SQL函数的有限子集,因为它是灵活构建的,而不是特定于SQL引擎的。因此,像IF语句这样的东西没有被实现到学说中,并且不会被实现,因为MySQL处理IF的方式,例如,与PostgreSQL不同(它甚至不存在)。
然而,Doctrine 2功能如此强大,允许您编写自己的功能,并扩展其功能,但我不建议这样做,除非真的有必要这样做。
您可以在其文档中找到有关用户定义函数和Doctrine的更多详细信息:
http://doctrine-orm.readthedocs.org/en/latest/cookbook/dql-user-defined-functions.html
我要做的是编写原始SQL来查询数据库。您必须创建自定义存储库以保持代码清洁和有序。
自定义存储库是实体的“扩展”。
例如,如果您有一个实体GH
,那么您的实体类如下所示:
<?php
namespace YourNamespace\ProjectName\WhateverBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* GH
*
* @ORM\Table(name="GH")
* @ORM\Entity(repositoryClass="YourNamespace\ProjectName\WhateverBundle\GHRepository")
*/
class Category {}
请注意添加到注释中的repositoryClass
语句,该语句指示客户存储库的位置。
然后在实体类所在的同一文件夹中创建一个存储库类。惯例是将其命名为“Repository”,因此在您的情况下它将是:GHRepository
并扩展父类EntityRepository
,您的自定义存储库类将如下所示:
<?php
namespace YourNamespace\ProjectName\WhateverBundle\Entity;
use Doctrine\ORM\EntityRepository;
use PDO;
class GH Repository extends EntityRepository {
}
然后,您可以在类中创建使用原始SQL查询数据库的公共函数。惯例是命名以findBy
或findAllBy
开头的函数,但这不是必需的。
例如,我的一个函数看起来像这样:
public function findAllProductsByCategory($categoryId) {
$pdo = $this->getEntityManager()->getConnection();
$findProductsQuery =
"SELECT
P.*
FROM
Products P
LEFT JOIN Types_Products TP ON TP.product_id = P.id
LEFT JOIN Types T ON TP.type_id = T.id
LEFT JOIN Categories_Types CT ON CT.type_id = T.id
LEFT JOIN Categories C ON CT.category_id = C.id
WHERE
C.id = :categoryId
GROUP BY
P.id";
$stmt = $pdo->prepare($findProductsQuery);
$stmt->bindParam(':categoryId', $categoryId, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
我可以在任何控制器中使用此功能:
$doctrine = $this->getDoctrine();
$em = $doctrine->getManager();
$categoryRepository = $em->getRepository('MyBundle:Category');
$products = $categoryRepository->findAllProductsByCategory($category->getId());
答案 1 :(得分:1)
我知道你不能在学说中做到这一点。在MySQL中,您将使用CASE
并且是特定于供应商的关键字。