使用 Doctrine NativeQuery 获取单行结果

Posted

技术标签:

【中文标题】使用 Doctrine NativeQuery 获取单行结果【英文标题】:Get single row result with Doctrine NativeQuery 【发布时间】:2012-07-06 02:38:08 【问题描述】:

我正在尝试使用 Doctrine 从本机查询返回单行。这是我的代码:

$rsm = new ResultSetMapping;
$rsm->addEntityResult('VNNCoreBundle:Player', 'p');
$rsm->addFieldResult('p', 'player_id', 'id');

$sql = " 
    SELECT player_id
      FROM players p
     WHERE CONCAT(p.first_name, ' ', p.last_name) = ?
";

$query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
$query->setParameter(1, $name);
$players = $query->getResult();

最后一行返回一个玩家列表,但我只想要一个结果。我该怎么做?

【问题讨论】:

【参考方案1】:

我在这里使用 fetchObject() 一个使用 Symfony 4.4 的小例子

    <?php 
    use Doctrine\DBAL\Driver\Connection;

    class MyController

    public function index($username)
      $queryBuilder = $connection->createQueryBuilder();
      $queryBuilder
        ->select('id', 'name')
        ->from('app_user')
        ->where('name = ?')
        ->setParameter(0, $username)
        ->setMaxResults(1);
      $stmUser = $queryBuilder->execute();

      dump($stmUser->fetchObject());

      //get_class_methods($stmUser) -> to see all methods
    
  

回复:

 
"id": "2", "name":"myuser"

【讨论】:

【参考方案2】:

您可以使用$query-&gt;getSingleResult(),如果找到多个结果,或者没有找到结果,则会抛出异常。 (请参阅此处的相关 phpdoc https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L791)

还有一个不太出名的$query-&gt;getOneOrNullResult(),如果找到多个结果就会抛出异常,如果没有找到结果则返回null。 (请参阅此处的相关 phpdoc https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L752)

【讨论】:

很好,甚至不知道 getOneOrNullResult,但这很有帮助! 如果你想得到一个数组:-&gt;getOneOrNullResult(Query::HYDRATE_ARRAY)【参考方案3】:

获取单行

$result = $this->getEntityManager()->getConnection()->fetchAssoc($sql)

获取所有记录

$result = $this->getEntityManager()->getConnection()->fetchAll($sql)

这里可以使用sql原生查询,一切正常。

【讨论】:

【参考方案4】:

->getSingleScalarResult() 将返回单个值,而不是数组。

【讨论】:

这是我正在寻找的 SELECT MIN(date)... 查询。返回不带数组的日期。谢谢。【参考方案5】:

如果有多个结果,getSingleResult()getOneOrNullResult() 都会抛出异常。 要解决此问题,您可以将 setMaxResults(1) 添加到您的查询构建器中。

 $firstSubscriber = $entity->createQueryBuilder()->select('sub')
        ->from("\Application\Entity\Subscriber", 'sub')
        ->where('sub.subscribe=:isSubscribe')
        ->setParameter('isSubscribe', 1)  
        ->setMaxResults(1)
        ->getQuery()
        ->getOneOrNullResult();

【讨论】:

对于任何尝试将 SetMaxResults(1) 与 NativeQuery 一起使用的人,不支持该方法 docs for version 2.3。 我对此解决方案有一个担忧——如果你们都断言应该有 0 或 1 个结果,但随后吞下了应该导致该断言为假的异常(通过 setMaxResults(1)) ,那么您可能会掩盖数据模型或应用程序的一个更隐蔽的问题。仅供参考。 如果你想得到一个数组:-&gt;getOneOrNullResult(Query::HYDRATE_ARRAY)【参考方案6】:

我只想要一个结果

表示您希望只返回一行。因此,要么调整您的查询,例如

SELECT player_id
FROM players p
WHERE CONCAT(p.first_name, ' ', p.last_name) = ?
LIMIT 0, 1

(然后按照 AdrienBrault 的建议使用 getSingleResult())或将行作为数组获取并访问第一项:

// ...
$players = $query->getArrayResult();
$myPlayer = $players[0];

【讨论】:

以上是关于使用 Doctrine NativeQuery 获取单行结果的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine2:使用 NativeQuery 和 ResultSetMapping 进行查询

在运行时覆盖 NativeQuery

使用 NativeQuery 的 MongoDB 聚合

Symfony2 项目中的 Doctrine2 映射问题

如何在spring数据仓库nativeQuery中使用oracle NVL函数

由 Doctrine2 (Symfony2) 生成的约束中的奇怪随机名称