如何使用Doctrine2构建类似查询继承的东西?

时间:2012-05-08 13:00:17

标签: symfony doctrine-orm

我正在使用Symfony2和Doctrine2构建一个小型网站。有博客文章,活动和新闻稿。每个都非常相似,我决定使用单表继承(STI)和一个名为' Node'的父表。

节点有:

  • a'已发布' field,是boolean
  • a' locale'字段,这是一个字符串,并且说“只有在此区域设置中才能显示”#。 (通过请求传入区域设置)。

默认情况下,我只想显示来自当前语言环境的已发布节点。

显然,我可以在存储库中创建大量查询,如下所示:

$this->createQueryBuilder('Event')
     ->where('Node.published = 1')
     ->where('Node.locale = :locale')

但这似乎不是很干。

那么如何构建一个其他查询可以继承的默认查询'从?这应该包括基于关系的默认Doctrine查询。

2 个答案:

答案 0 :(得分:4)

继承可能有点过头了。

为什么不创建一个小工厂方法,为您提供预配置的queryBuilder?

class NodeRepository extends Doctrine\ORM\EntityRepository {

    public function getLocalizedNodeQueryBuilder($type,$locale){
        return $this->getQueryBuilder($type)
            ->where('Node.published = 1')
            ->where('Node.locale = :locale')
            ->setParameter('locale',$locale);
    }
}

如果您确定总是希望以这种方式配置querybuilder,那么您可以执行相同的操作,并简单地覆盖getQueryBuilder。

答案 1 :(得分:2)

您不需要在存储库类中构建类似的东西。如果使用“Discriminator Map”设置单表继承,则最终会生成单独的类(实体)。当Doctrine与DBAL交互时,Doctrine将负责按“节点类型”进行过滤。

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/inheritance-mapping.html#single-table-inheritance

例如......

namespace MyProject\Model;

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"node" = "Node", "blogpost" = "Blogpost", "events" = "Events"})
 */
class Node
{
    // ...
}

/**
 * @Entity
 */
class Blogpost extends Node
{
    // ...
}

/**
 * @Entity
 */
class Events extends Node
{
    // ...
}


// get me all the blogposts
$blogposts = $em->getRepository('Blogpost')->findAll();

// get me all the events
$events = $em->getRepository('Events')->findAll();

这是特别有益的,因为您可以将“Blogpost”逻辑封装到自己的实体中,而不是尝试用其父类“Node”来表示它。