[英]Merge 2 queries in 1 Doctrine DQL
我正在使用帶有Symfony 2.8的Doctrine 2.4,並且正在嘗試建立一個友誼系統。
我有MateRelationship實體:
class MateRelationship
{
/**
* @var integer
*
* @ORM\Column(type="integer", name="id")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User")
* @ORM\JoinColumn(name="sender", referencedColumnName="id", nullable=false)
*
*/
private $sender;
/**
* @ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User")
* @ORM\JoinColumn(name="receiver", referencedColumnName="id", nullable=false)
*
*/
private $receiver;
/**
* @var \DateTime
*
* @ORM\Column(type="datetime", nullable=false)
*/
private $date;
/**
* @var boolean
*
* @ORM\Column(type="boolean", nullable=false)
*/
private $invitationAccepted;
我的目標是進行DQL查詢,以獲取給定用戶的所有接受的朋友關系(無論用戶是發送者還是接收者)。
我設法通過2個查詢並合並結果來完成此操作,但是它沒有經過優化,因此很難以這種方式實現$limit
。
public function getMates($user, $limit = 0){
$query1 = $this->_em->createQuery('SELECT m, u.nickname, u.username FROM AcmeUserBundle:MateRelationship m JOIN m.receiver u WHERE m.invitationAccepted = 1 AND m.sender = :user')
->setParameter('user', $user);
try{
$result1 = $query1->getResult();
}
catch(\Doctrine\ORM\NoResultException $e){
$result1 = [];
}
$query2 = $this->_em->createQuery('SELECT m, u.nickname, u.username FROM AcmeUserBundle:MateRelationship m JOIN m.sender u WHERE m.invitationAccepted = 1 AND m.receiver = :user')
->setParameter('user', $user);
try{
$result2 = $query2->getResult();
}
catch(\Doctrine\ORM\NoResultException $e){
$result2 = [];
}
return array_merge($result1, $result2);
}
我想要一個查詢,所以可以使用->setMaxResults($limit)
但我不知道如何在1中合並這兩個查詢。感謝您的幫助:)
您可以使用LEFT JOIN
和CASE
來獲得有效的用戶信息:
public function getMates($user, $limit = 0)
{
$dql = <<<DQL
SELECT
m,
CASE usen.nickname IS NULL WHEN TRUE THEN urec.nickname ELSE usen.nickname END AS nickname,
CASE usen.username IS NULL WHEN TRUE THEN urec.username ELSE usen.username END AS username,
CASE usen.nickname IS NULL WHEN TRUE THEN 'sender' ELSE 'receiver' END AS relationship
FROM AcmeUserBundle:MateRelationship m
LEFT JOIN m.sender usen
LEFT JOIN m.receiver urec
WHERE m.invitationAccepted = 1 AND (m.receiver = :user OR m.sender= :user)
DQL;
return $this->_em->createQuery($dql)
->setParameter('user', $user)
->setMaxResults($limit)
->getResult();
}
如果$result
為空,則它已經是一個空數組[]
。
注意:僅針對調用它們的getOneOrNullResult
, getSingleResult
或getSingleScalarResult
方法引發NoResultException
異常。
這是使用原則查詢構建器的建議
public function getMates($user, $limit = 0)
{
// Create query builder
$queryBuilder = $this->_em->getRepository("AcmeUserBundle:MateRelationship")->createQueryBuilder('m');
// Create 'or' expression
$or = $queryBuilder->expr()->orX();
$or
->add('m.sender = :user')
->add('m.receiver = :user');
// Create the query
$queryBuilder
->andWhere('m.invitationAccepted = 1')
->andWhere($or)
->setMaxResults($limit)
->setParameter('user', $user);
// Return the result
return $queryBuilder->getQuery()->getResult();
}
您可以簡單地通過在匹配:user
時輸入OR
來實現。 那可以是receiver
也可以是sender
。
SELECT m, usen.nickname, usen.username, urec.nickname, urec.username
FROM AcmeUserBundle:MateRelationship m
JOIN m.sender usen
JOIN m.receiver urec
WHERE m.invitationAccepted = 1 AND
(m.receiver = :user OR m.sender= :user)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.