多对多关系和查询构建器

时间:2014-12-03 11:14:34

标签: symfony doctrine

我想扩展我的用户存储库。我会找到具有指定角色的所有用户或 满足额外条件。

我尝试使用查询构建器进行一些查询,但没有成功。

以下是我的数据库结构示例。

表名:用户

+----+----------+-----------+
| id | isActive | isDeleted |
+----+----------+-----------+
|  1 |        1 |         0 |
+----+----------+-----------+

表名:角色

+----+-------+
| id | name  |
+----+-------+
|  1 | Admin |
+----+-------+

表名: user_role

用户和角色之间的ManyToMany关系

+---------+---------+
| user_id | role_id |
+---------+---------+
|       1 |       1 |
+---------+---------+

表名:距离

用户和桌距离之间的OneToMany关系

+----+---------+-----+------+
| id | user_id | lat | long |
+----+---------+-----+------+
|  1 |       1 |     |      |
+----+---------+-----+------+

我写了一个简单的SQL查询,这对我来说是正确的,但我不知道我怎么能意识到 与查询构建器的多对多关系。

SELECT u.id 
FROM user as u,  user_role  as ur 
WHERE u.id=ur.user_id and ur.role_id=1 OR 
(u.id not in (select user_id from distance) and ur.role_id=1 and u.id=ur.user_id);

有人可以告诉我如何解决这个问题吗?

更新

由于可读性和清晰度,我将仅展示实体的某些部分。

class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Exclude
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\Role", inversedBy="users")
     *
     */
    protected $roles;

    /**
     * @ORM\OneToMany(targetEntity="App\UserBundle\Entity\Distance", mappedBy="user", cascade={"persist", "remove"})
     * @Exclude
     */
    protected $distance;

}


class Role implements RoleInterface
{

    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="name", type="string", length=255)
     * @Exclude
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\User", mappedBy="roles")
     */
    private $users;
}


class Distance
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="distance", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

}

2 个答案:

答案 0 :(得分:0)

你可以尝试这样的DQL(或simillar)。请检查Doctrine DQL documenation

SELECT u FROM App\UserBundle\Entity\User u
INNER JOIN u.role r
LEFT JOIN u.distance d
WHERE r.id = 1 OR (r.id = 1 AND d IS NULL)

BTW你确定你的SQL没问题吗?我不确定这是否与

给出相同的结果
SELECT u.id 
FROM user as u,  user_role  as ur 
WHERE u.id=ur.user_id and ur.role_id=1

然后DQL将是微不足道的

SELECT u FROM App\UserBundle\Entity\User u
INNER JOIN u.role r
WHERE r.id = 1

答案 1 :(得分:0)

@ l3l0非常感谢,这解决了我的问题:)

我现在在我的用户存储库中添加了以下功能,并且每个都可以:)

public function getUsers2Crawl($role)
{
    $query = $this->getEntityManager()->createQuery('SELECT u FROM App\UserBundle\Entity\User u INNER JOIN u.roles r LEFT JOIN u.distance d WHERE r.id = $role->getId() OR (r.id = $role->getId() AND d IS NULL)');
    return $query->getResult();
}
相关问题