【问题标题】:Howto make join in DQL如何在 DQL 中加入
【发布时间】:2014-03-11 20:39:36
【问题描述】:

我正在尝试使用 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;

【问题讨论】:

  • 仅供参考 $this->getEntityManager() 已被弃用并可以通过 $this->getManager(); 替换不过很快就回答了……
  • 或者在你运行上述查询之前 $name 的值是多少。
  • 我在 EntityRepository 中调用 DQL 查询,因此“getManager()”不起作用。反正这不是重点。我在询问如何使用 DQL 查询获得特定结果。
  • $this->getDoctrine()->getManager();在 EntityRepository 中。这都是相对的,即使这不是您要寻找的答案。就像我如何告诉某人他们的 SQL 是可注入的,即使他们没有询问它是否是,等等。弃用的函数离被删除函数只有一步之遥。我询问了 $name 值,因为如果为 false,它将返回所有行,这就是正在发生的事情。
  • 您可以随时转储正在发生的实际 sql 查询。

标签: php sql symfony dql


【解决方案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 中使用这些示例。请记住在 Doctrine 文档中显示的所有注释前面加上 @ORM\

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

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

然后在 symfony 中,你必须这样写:

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

否则将无法正常工作。

【讨论】:

  • 谢谢这是我问题的答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多