symfony doctrine complex querybuilder

时间:2014-09-18 13:02:03

标签: php symfony doctrine-orm doctrine query-builder

也许简单但我的查询构建器没有返回我想要的东西。我会喜欢......哪里......和(......或......)

我尝试阅读学说文档但是,我不能说流利的英语,所以我不太了解学说文档(也许是法语翻译?)。

<?php
// $qb instanceof QueryBuilder

$qb->select(array('u')) // string 'u' is converted to array internally
   ->from('User', 'u')
   ->where($qb->expr()->orX(
       $qb->expr()->eq('u.id', '?1'),
       $qb->expr()->like('u.nickname', '?2')
   ))
   ->orderBy('u.surname', 'ASC'));

这是我的MySQL测试代码

select count(distinct(u.username)) from fos_user u join users_accounts ua ON u.id=ua.user_id join account acc ON acc.id = ua.account_id where u.id=48 and (acc.id=2 OR acc.id=5)

以下是查询构建器:

我使用服务是因为我不得不多次使用此功能。

/**
* Check if User exists in one of the connected user (Admin or SupAdmin) accounts
* argument : userID
* 
*/
public function userExists($userID)
    {       
        // Return accounts (array)
        $accounts   = $this->accountManager->listAccountsByConnectedUser();
        $repository = $this->em->getRepository('CMiNewsBundle:User');

        $qb = $repository->createQueryBuilder('u');

        $query = $qb
                    ->select('count(u)')
                    ->join ('u.accounts', 'acc')
                    ->where('u.id = :userID')
                    ->andwhere('acc.id = :accountID')
                    ->setParameters(array(
                      'userID'  => $userID,
                      'accountID'  => $accounts[0]->getId(),
                    ));

                   if (count($accounts) > 1) {


                    $accountMax = count($accounts);                         

                    for($acc=1; $acc<$accountMax; $acc++)
                    {
                        $query->orWhere('acc.id = :accountID_'.$acc.'')->setParameter('accountID_'.$acc.'', $accounts[$acc]->getId());
                    }
                   };

                   $query = $query->getQuery();
                   $result = $query->getResult();
        return $result;
    }

感谢您的建议

1 个答案:

答案 0 :(得分:0)

您可以在mysql中使用IN()重写您的查询,如下所示

SELECT 
  COUNT(DISTINCT (u.username)) 
FROM
  fos_user u 
  JOIN users_accounts ua 
    ON u.id = ua.user_id 
  JOIN account acc 
    ON acc.id = ua.account_id 
WHERE u.id = 48 
  AND acc.id IN(2,5) /* this is equivalent to acc.id = 2 or acc.id = 5 */

您正在运行的学说的当前查询忽略了您的条件,如果您有2个帐户ID,则查询将

WHERE u.id = 48 AND acc.id = 2 OR acc.id = 5

因此它会为acc.id = 5u.id提供记录,可以是任何其他ID


对于doctrine查询,您可以重写您的代码,如下所示,您必须构建一个帐户ID数组并在IN()子句中传递此数组

public function userExists($userID)
{
    // Return accounts (array)
    $accounts = $this->accountManager->listAccountsByConnectedUser();
    $repository = $this->em->getRepository('CMiNewsBundle:User');
    $qb = $repository->createQueryBuilder('u');
    $accounts=array();
    $accounts[]=$accounts[0]->getId();
    if (count($accounts) > 1) {
        $accountMax = count($accounts);
        for ($acc = 1; $acc < $accountMax; $acc++) {
            $accounts[]=$accounts[$acc]->getId();
        }
    }
    $query = $qb
        ->select('count(u) as your_count')
        ->join('u.accounts', 'acc')
        ->where('u.id = :userID')
        ->andwhere('acc.id IN(:accountID)')
        ->setParameters(array(
            'userID' => $userID,
            'accountID' => $accounts,
        ));
    $query = $query->getQuery();
    $result = $query->getResult();
    return $result;
}