doctrine2 - 实体是其成员

时间:2011-10-25 01:48:17

标签: php mysql doctrine-orm

为了举例:

我有以下架构:

users(id, name)
groups(id,name)
user_groups(user_id, group_id)

我想获取属于某个群组的用户。问题是,我知道组ID,所以我不想加入组表 - user_groups就足够了。

结果应该是

SELECT * FROM `users` AS u
LEFT JOIN `user_groups` AS ug ON (ug.`user_id` = u.`id)
WHERE ug.`group_id` = X
// i know the value of X

我在doctrine2中的尝试导致另一个groups表的连接。

我最接近的是:

SELECT u FROM models\User u WHERE ?1 MEMBER OF u.groups

但它也将LEFT JOIN加入“WHERE EXISTS(...)”

可以在没有本机查询的情况下完成(使用DQL /查询构建器)吗?

2 个答案:

答案 0 :(得分:3)

ORM优于ActiveRecord模式的一个优点是,您不需要为连接表创建新实体。

因此,当您使用Doctrine时,user_groups表将在两侧进行映射。

这意味着您无法直接访问user_groups表。除非你使用本机sql,我强烈反对。

因此,解决您的情况的最佳方法是在群组回购中使用findOneBy($group_id)并从中获取用户。这是理论上正确的实现方式。

- 编辑 - 您的评论:

是的,我同意从纯db POV中提高效率。

但如果没有本机查询,你将无法做到这一点,因为DQL,查询构建器以及与doctrine相关的所有内容都使用Entities来执行操作,并且由于您在设计中使用ORM,因此您将没有实体用于Join表。

否则,唯一的方法是将地图从a many to many relation from user to groups using join table更改为a one-to-many from users to user_groups and a many-to-one from user_groups to groups。这样,您将拥有user_groups的实体。

然后您可以直接使用该实体来获取用户。

即使它是一个黑客,它不是技术上和从理论上讲,这样使用是正确的。除非连接表当然还有其他责任。

答案 1 :(得分:0)

以下是您在DQL中的查询:

$query = $em->createQuery('SELECT u.id, u.name FROM Path\To\Users u LEFT JOIN u.groups g WHERE g.id = :group');
$query->setParameter('group', $group);
$users = $query->getResult();

我也倾向于在连接表方面考虑这样的查询,但是当你根据关联和实体包含的对象集合来思考时,Doctrine似乎更有意义。