如何在DQL中进行连接

时间:2014-03-11 20:39:37

标签: php sql symfony dql

我尝试使用DQL查询获取用户及其关联的角色。为了检查我为什么不能使用symfony2教程获得用户角色。

http://symfony.com/doc/current/cookbook/security/entity_provider.html

这些是表......

用户表:

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(255) | NO   |     | NULL    |                |
| password | varchar(255) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

user_role表:

+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| user_id | int(11) | NO   | PRI | NULL    |       |
| role_id | int(11) | NO   | PRI | NULL    |       |
+---------+---------+------+-----+---------+-------+

角色表:

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| role  | varchar(255) | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

这就是我试图在UserRepository中实现的方法:

public function findRolesByUsername($name) {
    $em = $this->getEntityManager();
    $query = $em->createQuery('SELECT u.username, r.role 
                               FROM TestLoginBundle:User u
                               JOIN TestLoginBundle:Role r
                               WHERE u.username = :user')
                               ->setParameter('user', $name);
    $result = $query->getResult();

    return $result;
}

获得此结果......

+----------+------------+
| username | role       |
+----------+------------+
| admin    | ROLE_ADMIN |
| admin    | ROLE_USER  |
+----------+------------+

想要这个...

+----------+------------+
| username | role       |
+----------+------------+
| admin    | ROLE_ADMIN |
+----------+------------+

我知道如何使用SQL语句获得此结果,但不知道使用DQL。

SQL查询:

SELECT u.username, r.role 
FROM User u 
JOIN user_role ur 
ON u.id = ur.user_id 
JOIN Role r 
ON ur.role_id = r.id;

1 个答案:

答案 0 :(得分:1)

问题似乎存在于您的实体中。如果您希望DQL按照设计工作的方式工作,则需要为实体添加适当的注释。

看起来你正面临着经典的一对多,单向问题:

例如:

<强> Users.php

<?php

/**
 *@ORM\Table("Users")
 *@ORM\Entity
 */

class Users {
    /**
     * @ORM\ManyToMany(targetEntity="Role")
     * @ORM\JoinTable(name="users_roles",
     *      joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="role_id", referencedColumnName="id")}
     *      )
     */
    private $roles;

    public function __construct() {
        $this->roles = new ArrayCollection();
    }
}

然后它应该只是写一个DQL,如:

$query = $em->createQuery('
SELECT
    u.username, u.roles.role
FROM
    TestLoginBundle:User u
WHERE
    u.username = :user
')->setParameter('user', $name);

为了获得您想要的结果。

阅读Doctrine文档中的以下页面:

http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html

它们提供了比上面显示的更深入和更全面的例子。但是,如果您打算在Symfony中使用这些示例。请记住将@ORM\添加到Doctrine文档中显示的所有注释中。

例如,如果Doctrine的文档告诉您使用:

/**
 * ManyToMany(targetEntity="Role")
 */

然后在symfony中,你必须把它写成:

/**
 * @ORM\ManyToMany(targetEntity="Role")
 */

否则,它将无效。