Doctrine DQL JOIN

时间:2011-10-29 16:40:14

标签: php join orm doctrine-orm dql

我使用Doctrine 2映射了以下实体:

class Zone
{
    /**
     * @ManyToOne(targetEntity="Zone", inversedBy="children")
     * @var Zone
     */
    protected $parent;

    /**
     * @OneToMany(targetEntity="Zone", mappedBy="parent")
     * @var Zone[]
     */
    protected $children;

    /**
     * @ManyToMany(targetEntity="Zone")
     * @var Zone[]
     */
    protected $descendants;
}

class Restaurant
{
    /**
     * @ManyToOne(targetEntity="Zone")
     * @var Zone
     */
    protected $zone;
}

基本上,区域有父母,因此有孩子。因为孩子们可能自己有孩子,所以每个区域都会保留所有孩子的列表。

每家餐厅都有一个区域。

我想要做的是执行DQL JOIN以返回特定区域中的所有餐厅(包括其所有后代)。

如果我必须在纯SQL中执行此操作,我会写:

SELECT r.* from Zone z
JOIN ZoneDescendant d ON d.zoneId = z.id
JOIN Restaurant r ON r.zoneId = d.descendantId
WHERE z.id = ?;

是否可以使用Doctrine DQL执行此操作,而不在区域上添加$restaurants属性,并且必须无用地复杂化域模型?

2 个答案:

答案 0 :(得分:9)

好的,我终于找到了一种方法只使用JOIN(在MySQL上显着更快):

SELECT r
FROM Restaurant r,
     Zone z
JOIN z.descendants d
WHERE r.zone = d
AND z = ?1;

答案 1 :(得分:1)

我能想到在单个DQL查询中执行此操作的唯一方法是使用子查询:

SELECT r FROM Restaurant r WHERE r.zone IN (SELECT zc.id FROM r.zone z JOIN z.children zc WHERE z.id = :zoneId) OR r.zone = :zoneId