我正在使用Doctrine 2.4和Symfony 2.8,而我正试图建立一个友谊系统。
我有我的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中合并这两个查询。
谢谢你的帮助:)
答案 0 :(得分:1)
您可以使用if(Pattern.matches("[a-zA-Z]:", path))
path = path.substring(2);
和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
。
注意: []
例外仅针对调用它们的NoResultException
,getOneOrNullResult
或getSingleResult
方法抛出。
答案 1 :(得分:1)
以下是使用doctrine查询构建器
的提案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();
}
答案 2 :(得分:-2)
您只需在匹配OR
时添加:user
即可。这可以是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)