使用AND和OR的查询构建器

时间:2019-03-11 08:55:32

标签: symfony doctrine query-builder

我在 Symfony 3.4 flex 中工作,我需要像这样做一个querybuilder:

所有在True AND媒体上带有“ 已发布”的媒体都是 TYPE OF type AND ((condition 1) OR (condition 2) OR (condition 3)),带有symfony准则查询构建器。这两个条件已经为真(已发布和:instance的实例):

 $queryBuilder = $this->createQueryBuilder('m')
        ->chere('m.published = :published')
        ->andWhere('m INSTANCE OF :instance');

/* 
WHERE m.published = true AND m INSTANCE OF :instance

AND (
    //    ('m.startDate <= :today AND m.endDate >= :today')
    // OR ('m.startDate IS NULL AND m.endDate >= :today')
    // OR ('m.startDate IS NULL AND m.endDate IS NULL')
    // OR ('m.startDate <= :today AND m.endDate IS NULL')
*/

当我尝试类似的事情时:

$queryBuilder->andWhere($queryBuilder->expr()->andX(
            $queryBuilder->expr()->lte('m.startDate', ':today'),
            $queryBuilder->expr()->gte('m.endDate', ':today'))
   );

但是它不起作用,它返回类似:

WHERE (
    (m.published = 1 AND m.type IN (:type)) // I already needed this in all cond
    AND m.start_date <= :today AND m.end_date >= :today // cond 1
)

    OR (m.start_date IS NULL :today AND m.end_date IS NULL) // cond 2
    OR ... // cond 3

所以我在((m.published = 1 AND m.type IN (:type)))的情况不仅要在所有情况下都必须在所有情况下

你有什么主意吗?

谢谢。

2 个答案:

答案 0 :(得分:2)

据您所知,使用DQL就像这样:

 <input pattern='^[-\w\.\$@\*\!]{1,30}$' />

它将为您提供以下DQL查询:

//Important to have it initialized alone so you can use it for expressions
$qb=$this->createQueryBuilder('m');

$qb->andWhere($qb->expr()->andX(
    "m.published=1",
    "m INSTANCE OF :instance",
    $qb->expr()->orX(
        $qb->expr()->andX("m.startDate <= :today", "m.endDate >= :today"),
        $qb->expr()->andX("m.startDate IS NULL", "m.endDate >= :today"),
        $qb->expr()->andX("m.startDate IS NULL", "m.endDate IS NULL"),
        $qb->expr()->andX("m.startDate <= :today", "m.endDate IS NULL")
    )
))
->setParameters(array(
    'instance'=>$instance,
    'today'=>$today,
))
->getQuery()
->execute();

一些提示:

从不使用SELECT m FROM AppBundle\Entity\Media m WHERE m.published=1 AND m INSTANCE OF :instance AND ((m.startDate <= :today AND m.endDate >= :today) OR (m.startDate IS NULL AND m.endDate >= :today) OR (m.startDate IS NULL AND m.endDate IS NULL) OR (m.startDate <= :today AND m.endDate IS NULL)) where(),这势必会在某一天给您带来麻烦
您可以详细了解here

始终在查询中使用双引号。 Doctrine仅接受查询中字符串的单引号

答案 1 :(得分:1)

您可以这样做:

 $queryBuilder = $this->createQueryBuilder('m')
        ->where("((m.published = true AND m INSTANCE OF :instance) AND
                      (
                          (m.startDate <= :today AND m.endDate >= :today) OR
                          (m.startDate IS NULL AND m.endDate >= :today) OR
                          (m.startDate IS NULL AND m.endDate IS NULL) OR
                          (m.startDate <= :today AND m.endDate IS NULL)
                      )
                 )"
               );