Doctrine:如何按条件在订单中添加if语句?

时间:2014-07-31 14:55:58

标签: symfony doctrine-orm

我尝试编写这种查询:

    $qb = $this
        ->createQueryBuilder()
        ->select('gh')
        ->orderBy("IF(gh.language = 'en', 1, 0)", 'desc')
        ->getQuery();

它如何运作?

2 个答案:

答案 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查询数据库的公共函数。惯例是命名以findByfindAllBy开头的函数,但这不是必需的。

例如,我的一个函数看起来像这样:

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并且是特定于供应商的关键字。