使用 Doctrine ORM 的*** EXISTS 查询

Posted

技术标签:

【中文标题】使用 Doctrine ORM 的*** EXISTS 查询【英文标题】:Top level EXISTS query using Doctrine ORM 【发布时间】:2021-01-15 12:33:45 【问题描述】:

我在普通 SQL 中有一个这样的查询(当然原来的更复杂,但仍然足够简单,我很确定那部分至少是正确的):

SELECT EXISTS (SELECT 1 FROM mytable WHERE 1 = 1)

问题是:我如何使用 Doctrine ORM DQL 做到这一点?

我目前的状态如下:

$queryBuilder = $this->em->createQueryBuilder();
$subQueryBuilder = $this->em->createQueryBuilder();

$subQueryBuilder
    ->select('1')
    ->from(MyEntity::class, 'b')
    ->where($subQueryBuilder->expr()->eq('1', '1'))
;

return (bool) $queryBuilder
    ->select('EXISTS(' . $subQueryBuilder->getDQL() . ')')
    ->getQuery()
    ->getSingleScalarResult()
;

这将引发解析错误,因为 EXISTS 是一个未知函数(并且没有内置函数可以解决此问题)。使用本机查询也不起作用,但我可能把它搞砸了,所以非常感谢一个正确的例子,包括结果集映射。

在 SO 上有类似问题的答案,但我还没有找到这个确切的问题。

Query with EXISTS for Doctrine Symfony2(回答在 WHERE 部分使用 EXISTS 的情况) Doctrine2 DBAL Exists query 回答了正确的问题,但仅适用于 Doctrine DBAL,而不适用于 ORM。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

好的,尽管感觉有点不对劲,我还是通过使用原生查询解决了这个问题。这里仅供参考(尽管仍有待改进):

$subQueryBuilder = $this->em->createQueryBuilder();

$subQueryBuilder
    ->select('1')
    ->from(MyEntity::class, 'b')
    ->where($subQueryBuilder->expr()->eq('foo', '?'))
;

$rsm = new ResultSetMappingBuilder($this->em);
$rsm->addScalarResult('x', 'x', 'boolean');

$query = $this->em
    ->createNativeQuery('SELECT EXISTS(' . $subQueryBuilder->getQuery()->getSQL() . ') as x', $rsm)
;

return (bool) $query
    ->setParameter(1, 'bar')
    ->getSingleScalarResult()
;

【讨论】:

以上是关于使用 Doctrine ORM 的*** EXISTS 查询的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine ORM 使用啥机制来创建“持久”对象?

为啥使用 Doctrine 而不是 CakePHP 的标准数据库 ORM?

使用 Doctrine ORM 注释扩展功能

使用 Doctrine ORM 查询当天的生日

Symfony2:传递给 Doctrine\ORM\EntityRepository::__construct() 的参数 2 必须是 Doctrine\ORM\Mapping\ClassMetada

Zend/Doctrine 不能执行 ORM 操作,表已经存在