symfony - doctrine - 恢复我的 bdd 的所有数据,除了少数
symfony - doctrine - Recover all the data of my bdd except a few
我需要 queryBuilder 方面的帮助。
我搜索了一个 queryBuilderMethod,得到了除少数之外的所有数据。
例如在 sql 中有一个 table 它是这样的:
"select * from table Where user != "a" && user != "b" && user != c [...]"
我的 symfony 应用程序中有 3 个实体:
用户 => 一对多 => 照片 => 一对多 => 评分照片
我想获取当前用户尚未评分的用户。
下面的代码:
用户
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORM\Column(name="facebook_id", type="string", length=255, nullable=true) */
protected $facebook_id;
/** @ORM\Column(name="facebook_access_token", type="string", length=255, nullable=true) */
protected $facebook_access_token;
/** @ORM\Column(name="sex_target", type="integer", nullable=true) */
protected $sex_target;
/** @ORM\Column(name="sex", type="integer", nullable=true) */
protected $sex;
/**
* @ORM\OneToMany(targetEntity="Photo", mappedBy="user")
*/
protected $photo;
/**
* @ORM\OneToMany(targetEntity="RatingsPhoto", mappedBy="userMap",
* cascade={"persist", "remove"})
*/
protected $ratingsUser;
public function __construct()
{
$this->photo = new ArrayCollection();
$this->ratingsUser = new ArrayCollection();
}
}
照片
class Photo
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="user", referencedColumnName="id", nullable=false)
*/
protected $user;
/**
* @ORM\OneToMany(targetEntity="RatingsPhoto", mappedBy="photoMap",
* cascade={"persist", "remove"})
*/
protected $ratingsPhoto;
/**
* @var int
*
* @ORM\Column(name="numeroPlayer", type="integer", nullable=true)
*/
protected $numeroPlayer;
/**
* @var int
*
* @ORM\Column(name="nbrChoosen", type="integer", nullable=true)
*/
protected $nbrChoosen;
/**
* @var string
*
* @ORM\Column(name="photoName", type="string", length=255, unique=true, nullable=false)
*/
protected $photoName;
/**
* @ORM\Column(type="string", length=255, nullable=false)
* @var string
*/
protected $image;
/**
* @var \DateTime
*
* @ORM\Column(name="dateAdd", type="datetime")
*/
protected $dateAdd;
/**
* Constructor
*/
public function __construct()
{
$this->ratingsPhoto = new ArrayCollection();
}
}
评分照片
class 评分图片
{
public function __construct()
{
}
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="ratingsUser")
* @ORM\JoinColumn(name="user", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $userMap;
/**
* @ORM\ManyToOne(targetEntity="Photo", inversedBy="ratingsPhoto")
* @ORM\JoinColumn(name="photo", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $photoMap;
/**
* @var int
*
* @ORM\Column(name="note", type="integer", nullable=false)
*/
protected $note;
/**
* @var \DateTime
*
* @ORM\Column(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(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
先澄清一下。这不是 100% 正确:
User => one to many => Photo => one to many => RatingsPhoto
您拥有的是具有附加属性的经典多对多关系,不再是 m:n 关系,而是引入了您的专用关系实体 RatingsPhoto
所以你基本上拥有的是
用户 <OneToMany> RatingsPhoto <ManyToOne> 照片
最重要的是,每个用户可以拥有多张照片,这是 Photo
的一种所有权
用户 <OneToMany> 照片
首先是一个小建议,将 User:photo 属性重命名为 User:photos 以反映正确的关系。
/**
* @ORM\OneToMany(targetEntity="Photo", mappedBy="user")
*/
protected $photos;
关于您的查询:
I want to get a user who has not yet rated by the current user.
您应该使用子查询构建查询,例如 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(\Doctrine\ORM\AbstractQuery::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(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY)
;
我需要 queryBuilder 方面的帮助。
我搜索了一个 queryBuilderMethod,得到了除少数之外的所有数据。
例如在 sql 中有一个 table 它是这样的:
"select * from table Where user != "a" && user != "b" && user != c [...]"
我的 symfony 应用程序中有 3 个实体:
用户 => 一对多 => 照片 => 一对多 => 评分照片
我想获取当前用户尚未评分的用户。
下面的代码:
用户
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORM\Column(name="facebook_id", type="string", length=255, nullable=true) */
protected $facebook_id;
/** @ORM\Column(name="facebook_access_token", type="string", length=255, nullable=true) */
protected $facebook_access_token;
/** @ORM\Column(name="sex_target", type="integer", nullable=true) */
protected $sex_target;
/** @ORM\Column(name="sex", type="integer", nullable=true) */
protected $sex;
/**
* @ORM\OneToMany(targetEntity="Photo", mappedBy="user")
*/
protected $photo;
/**
* @ORM\OneToMany(targetEntity="RatingsPhoto", mappedBy="userMap",
* cascade={"persist", "remove"})
*/
protected $ratingsUser;
public function __construct()
{
$this->photo = new ArrayCollection();
$this->ratingsUser = new ArrayCollection();
}
}
照片
class Photo
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="user", referencedColumnName="id", nullable=false)
*/
protected $user;
/**
* @ORM\OneToMany(targetEntity="RatingsPhoto", mappedBy="photoMap",
* cascade={"persist", "remove"})
*/
protected $ratingsPhoto;
/**
* @var int
*
* @ORM\Column(name="numeroPlayer", type="integer", nullable=true)
*/
protected $numeroPlayer;
/**
* @var int
*
* @ORM\Column(name="nbrChoosen", type="integer", nullable=true)
*/
protected $nbrChoosen;
/**
* @var string
*
* @ORM\Column(name="photoName", type="string", length=255, unique=true, nullable=false)
*/
protected $photoName;
/**
* @ORM\Column(type="string", length=255, nullable=false)
* @var string
*/
protected $image;
/**
* @var \DateTime
*
* @ORM\Column(name="dateAdd", type="datetime")
*/
protected $dateAdd;
/**
* Constructor
*/
public function __construct()
{
$this->ratingsPhoto = new ArrayCollection();
}
}
评分照片
class 评分图片 {
public function __construct()
{
}
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="ratingsUser")
* @ORM\JoinColumn(name="user", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $userMap;
/**
* @ORM\ManyToOne(targetEntity="Photo", inversedBy="ratingsPhoto")
* @ORM\JoinColumn(name="photo", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $photoMap;
/**
* @var int
*
* @ORM\Column(name="note", type="integer", nullable=false)
*/
protected $note;
/**
* @var \DateTime
*
* @ORM\Column(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(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
先澄清一下。这不是 100% 正确:
User => one to many => Photo => one to many => RatingsPhoto
您拥有的是具有附加属性的经典多对多关系,不再是 m:n 关系,而是引入了您的专用关系实体 RatingsPhoto
所以你基本上拥有的是
用户 <OneToMany> RatingsPhoto <ManyToOne> 照片
最重要的是,每个用户可以拥有多张照片,这是 Photo
的一种所有权用户 <OneToMany> 照片
首先是一个小建议,将 User:photo 属性重命名为 User:photos 以反映正确的关系。
/**
* @ORM\OneToMany(targetEntity="Photo", mappedBy="user")
*/
protected $photos;
关于您的查询:
I want to get a user who has not yet rated by the current user.
您应该使用子查询构建查询,例如 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(\Doctrine\ORM\AbstractQuery::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(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY)
;