我需要 queryBuilder 的帮助。
我搜索查询构建器方法,获取除少数数据之外的所有数据。
例如,在带有一个表的SQL中,它是这样的:
"select * from table Where user != "a" && user != "b" && user != c [...]"
我的 Symfony 应用程序中有 3 个实体:
用户 =>一对多 =>照片 =>一对多 =>评分照片
我想获取尚未按当前用户评分的用户。
下面的代码:
用户
class User extends BaseUser
{
/**
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORMColumn(name="facebook_id", type="string", length=255, nullable=true) */
protected $facebook_id;
/** @ORMColumn(name="facebook_access_token", type="string", length=255, nullable=true) */
protected $facebook_access_token;
/** @ORMColumn(name="sex_target", type="integer", nullable=true) */
protected $sex_target;
/** @ORMColumn(name="sex", type="integer", nullable=true) */
protected $sex;
/**
* @ORMOneToMany(targetEntity="Photo", mappedBy="user")
*/
protected $photo;
/**
* @ORMOneToMany(targetEntity="RatingsPhoto", mappedBy="userMap",
* cascade={"persist", "remove"})
*/
protected $ratingsUser;
public function __construct()
{
$this->photo = new ArrayCollection();
$this->ratingsUser = new ArrayCollection();
}
}
相片
class Photo
{
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORMManyToOne(targetEntity="User")
* @ORMJoinColumn(name="user", referencedColumnName="id", nullable=false)
*/
protected $user;
/**
* @ORMOneToMany(targetEntity="RatingsPhoto", mappedBy="photoMap",
* cascade={"persist", "remove"})
*/
protected $ratingsPhoto;
/**
* @var int
*
* @ORMColumn(name="numeroPlayer", type="integer", nullable=true)
*/
protected $numeroPlayer;
/**
* @var int
*
* @ORMColumn(name="nbrChoosen", type="integer", nullable=true)
*/
protected $nbrChoosen;
/**
* @var string
*
* @ORMColumn(name="photoName", type="string", length=255, unique=true, nullable=false)
*/
protected $photoName;
/**
* @ORMColumn(type="string", length=255, nullable=false)
* @var string
*/
protected $image;
/**
* @var DateTime
*
* @ORMColumn(name="dateAdd", type="datetime")
*/
protected $dateAdd;
/**
* Constructor
*/
public function __construct()
{
$this->ratingsPhoto = new ArrayCollection();
}
}
收视率照片
班级评分照片 {
public function __construct()
{
}
/**
* @var int
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORMManyToOne(targetEntity="User", inversedBy="ratingsUser")
* @ORMJoinColumn(name="user", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $userMap;
/**
* @ORMManyToOne(targetEntity="Photo", inversedBy="ratingsPhoto")
* @ORMJoinColumn(name="photo", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $photoMap;
/**
* @var int
*
* @ORMColumn(name="note", type="integer", nullable=false)
*/
protected $note;
/**
* @var DateTime
*
* @ORMColumn(name="dateNote", type="datetime", nullable=false)
*/
protected $dateNote;
请求查询我尝试过但确实有效
$result = $this->getEntityManager()
->createQuery(
'SELECT p, u, r
FROM AppBundle:Photo p
LEFT JOIN p.user u
LEFT JOIN p.RatingsPhoto r
WHERE u != :user
AND r.user != :user
AND u.sex = :sex
order By Rand()'
)
->setParameters(array('user' => $user, 'sex' => $user
->getSexTarget()))
->getResult(DoctrineORMAbstractQuery::HYDRATE_ARRAY);
只是先澄清一下。这不是 100% 正确的:
用户 =>一对多 =>照片 =>一对多 =>评分照片
您那里有一个具有附加属性的经典多对多关系,它不再是 m:n 关系,而是引入了您的专用关系实体评级照片
所以你基本上拥有的是
用户<一对多评级照片<多对一照片
最重要的是,每个用户都可以拥有多张照片,这是照片的所有权
用户<一对多照片
首先是一个小建议,将用户:照片属性重命名为用户:照片,以便它反映正确的关系。
/**
* @ORMOneToMany(targetEntity="Photo", mappedBy="user")
*/
protected $photos;
关于您的查询:
我想获取尚未按当前用户评分的用户。
您应该使用子查询构建查询,例如get all users that are not in (a list of users which photos have been rated by the current user)
:
您可以尝试这样的事情(未经测试):
$result = $this->getEntityManager()
->createQuery(
'SELECT u
FROM AppBundle:User u
WHERE u.id not in
(
SELECT ru.i FROM AppBundle:RatingsPhoto r
LEFT JOIN u.photos p,
LEFT JOIN p.user ru
WHERE r.userMap = :user
)
AND u.sex = :sex
order By Rand()'
)
->setParameters(array('user' => $user, 'sex' => $user
->getSexTarget()))
->getResult(DoctrineORMAbstractQuery::HYDRATE_ARRAY);
最后我找到了答案,如果可以帮助某人,我将代码放在下面:
$result = $queryBuilder
->select(['p, ru, u'])
->from('AppBundle:Photo', 'p')
->leftJoin('p.ratingsPhoto', 'ru')
->leftJoin('p.user', 'u')
->where('ru.id IS NULL')
->Orwhere($queryBuilder->expr()->not($queryBuilder->expr()->exists('
SELECT sr.id
FROM AppBundle:RatingsPhoto sr
WHERE sr.userMap = :user'
)))
->andWhere('u.sex = :sex')
->setParameters(array('user' => $user, 'sex' => $user->getSexTarget()))
->getQuery()
->getResult(DoctrineORMAbstractQuery::HYDRATE_ARRAY)
;