Symfony2,创建querybuilder where子句,不为空或不为空

Posted

技术标签:

【中文标题】Symfony2,创建querybuilder where子句,不为空或不为空【英文标题】:Symfony2, create querybuilder where clause, not empty or not null 【发布时间】:2016-04-17 01:30:56 【问题描述】:

我在实体中有一个类型数组字段,

MyEntity.php

/**
 * @var string
 *
 * @ORM\Column(name="excepcionMenu", type="array", length=255, nullable=true)
 */
private $excepcion;

我想要一个 QueryBuilder$excepcion 字段中选择 not emptynot null

我在努力 MyEntityRepository.php

public function findAllExcepcionesByItem($itemId) 

    $query = $this->createQueryBuilder('p')
            ->leftJoin('p.item', 'i')
            ->where('i.id = :actual')->setParameter('actual', $itemId)
            ->andWhere('p.excepcion IS NOT NULL')
            ->getQuery();

    return $query->getResult();

但这会返回所有表记录。

public function findAllExcepcionesByItem($itemId) 

    $query = $this->createQueryBuilder('p')
            ->leftJoin('p.item', 'i')
            ->where('i.id = :actual')->setParameter('actual', $itemId)
            ->andWhere('p.excepcion IS NULL')
            ->getQuery();

    return $query->getResult();

但这会返回零记录。

数据库中的这个字段以这种方式存储值:

a:0: // empty
N; // null
a:2:i:0;i:2;i:1;i:4; // not empty or not null

是否可以使用 QueryBuilder 来完成,还是应该使用 DQL 来完成?

非常感谢


更新的解决方案由@Attila Szalay 提供

public function findAllExcepcionesByItem($itemId) 

    $query = $this->createQueryBuilder('p')
            ->leftJoin('p.item', 'i')
            ->where('i.id = :actual')->setParameter('actual', $itemId)
            ->andWhere('p.excepcion != :null')->setParameter('null', serialize(null)) //not null
            ->andWhere('p.excepcion != :empty')->setParameter('empty', serialize([])) //not empty
            ->getQuery();

    return $query->getResult();

【问题讨论】:

为什么$excepcion是字符串类型而列类型是数组? 因为它必须保存几个可能的选项。 Twig 上的表单呈现多个复选框。 你知道php中数组不能为空吗? 我知道,但是教义中的数组类型并不完全是php中的数组。去掉实体中字段定义的nullable=true,结果还是一样,新建一个空项,数据库中存储的值还是N;,查询结果也是。 【参考方案1】:

对我有用的问题的另一个解决方案是:

public function findAllExcepcionesByItem($itemId) 
    $query = $this->createQueryBuilder('p')
        ->leftJoin('p.item', 'i')
        ->where("i.id = :actual")->setParameter("actual", $itemId)
        ->andWhere("p.excepcion != ''") // NOT EMPTY
        ->andWhere("p.excepcion IS NOT NULL") // NOT NULL
        ->getQuery();
    return $query->getResult();

【讨论】:

->andWhere("p.excepcion IN NOT NULL") // NOT NULL IN 还是 IS ? :)【参考方案2】:

您的数据在数据库中存储为serialized“字符串”,因此 NULL 值将是“N;”字符串,它不是数据库引擎的 NULL 值。

试试这个:

 $query = $this->createQueryBuilder('p')
        ->leftJoin('p.item', 'i')
        ->where('i.id = :actual')->setParameter('actual', $itemId)
        ->andWhere('p.excepcion != :null')->setParameter('null', 'N;') //not null
        ->getQuery();

【讨论】:

你是对的,并没有陷入这个细节:) 现在我只需要检查a:0: 谢谢 您可以使用serialize(null) 进行NULL 检查,而不是'N;' 字符串和serialize([]) 用于空数组。【参考方案3】:
$qb = $this->createQueryBuilder('p');
$query = $qb->leftJoin('p.item', 'i')
        ->where('i.id = :actual')->setParameter('actual', $itemId)
        ->andWhere($qb->expr()->isNotNull("p.excepcion"))
        ->getQuery();

简而言之,您需要使用Expr 类which is explained in further detail in the QueryBuilder chapter of Doctrine's documentation。但是,我只是向您展示了如何使用它!

【讨论】:

非常感谢,但是结果和不使用正则表达式完全一样。喜欢->andWhere('p.excepcion IS NOT NULL')。我认为问题在于字段数组的类型。【参考方案4】:

您的存储库方法完全正确。

但是,数组不能为空。如果它为空,那么它不是一个数组:它是空的。

解决方案可能是更改列excepcionMenu 的类型。

【讨论】:

谢谢@scoolnico,我已经在您对主要问题的评论中回答了这个问题。

以上是关于Symfony2,创建querybuilder where子句,不为空或不为空的主要内容,如果未能解决你的问题,请参考以下文章

symfony2:如何在 QueryBuilder 中使用 group_concat

Symfony 2,QueryBuilder,多个和Where具有相同的参数

Doctrine queryBuilder:addOrderBy() 方法中的 SQL 注入风险?

如何使用 Doctrine 在 Symfony2 中实现子查询?

Symfony2 表单 > 实体字段类型 > 查询构建器 > 可能的子选择?

创建knex queryBuilder并稍后执行