1

我正在用 Symfony2 和 Doctrine2 构建一个小型网站。有博客文章、活动和新闻稿。它们中的每一个都非常相似,因此我决定将单表继承 (STI) 与称为“节点”的父表一起使用。

节点有:

  • 一个“已发布”字段,它是布尔值
  • 一个“语言环境”字段,它是一个字符串,表示“这只在这个语言环境中显示”。(语言环境是通过请求传入的)。

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

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

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

但这似乎不是很干燥。

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

4

2 回答 2

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);
    }
}

您可以做同样的事情,如果您确定始终希望以这种方式配置查询构建器,则只需覆盖 getQueryBuilder。

于 2012-05-08T20:39:56.873 回答
2

您不需要在存储库类中构建任何类似的东西。如果您使用“鉴别器映射”设置单表继承,您最终会得到单独的类(实体)。当 Doctrine 与 DBAL 交互时,它将按照您的“节点类型”进行过滤。

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();

这是特别有益的,因为您将能够将“博客帖子”逻辑封装到它自己的实体中,而不是试图用它的父类“节点”来表示它。

于 2012-05-08T13:46:49.600 回答