Doctrine单表继承查询所有实例

时间:2014-01-08 05:44:27

标签: php symfony doctrine dql single-table-inheritance

我正在研究通知系统,所以我有一个通知抽象类和子类(forumPostNotification,privateMessageNotification等)。它们使用单​​表继承存储,因此它们都在一个具有区分字段的表中。

我想立即获取适用于用户的所有通知,而不必单独查询每种类型的通知,但是我不确定如何在DQL / symfony中执行此操作(这很容易SQL)。

我相信:( Doctrine 2: how to write a DQL select statement to search some, but not all the entities in a single table inheritance table)与我想要实现的类似,但我不确定如何查询抽象对象。它也不在Entity目录中,而是在Entity / Notifications / Notification.php中。

我会添加一些代码以澄清:

Notification.php

/**
 * Notification Class    
 *@ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "notification"="Notification",
 *     "forumPostNotification"="ForumPostNotification",
 *     ...
 * })
 * @ORM\Table(name="notification")
 */
abstract class Notification
{
  /**
   * @ORM\ManyToOne(targetEntity="Acme\MainBundle\Entity\User", inversedBy="notifications")
   * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
   */
  private $user;
  //...
}

ForumPostNotification.php

/**
 * Forum Post Notification
 * @ORM\Entity
 */
class ForumPostNotification extends Notification
{
  //..
}

PrivateMessageNotification.php

/**
 * Private Message Notification
 * @ORM\Entity
 */
class PrivateMessageNotification extends Notification
{
  //..
}

我希望能够以这样或那样的方式做这样的事情(我明白我无法从Notification中查询,因为它是一个抽象类。我只是这样写它来表达我的意思喜欢实现):

$notifications = $em->createQuery('
  SELECT n
  FROM AcmeMainBundle:Notification n
  WHERE n.dateDeactivated IS NULL
  ORDER BY n.dateCreated ASC
')->getResult();

2 个答案:

答案 0 :(得分:2)

我们已经创建了与订单和产品类似的情况。因为您可以在一个订单中包含不同类型的产品,所以我们创建了一个父类Product并继承了ex。 SpecialProduct,SalesProduct等。

我们能够定义Order(在您的情况下是User)和“Product”(在您的情况下是Notification)之间的关系,这就是全部。我们通过$ order-> getProducts()获得订单的每个产品。该方法返回一个包含特定类ex

的精心准备的产品列表
order->products[SingleProduct, SingleProduct, SingleProduct, SpecialProduct, SalesProduct, SingleProduct]

所以,总之。要为每个用户获取所有通知,您只需要做一件事就是在用户和抽象父类之间定义正确的关系。

这很简单,但是......当你只获得特定类型的通知时,它并不是那么好。您链接中传递的查询并不漂亮。在我看来,你应该创建一个合适的queryBuilder - 它非常相似。

最后你不能使用$ user-> getNotifications(),但你必须直接从存储库获取通知 -

$em->get('AcmeBundle:User')->getForumPostNotifications()  

亲切的问候, 彼得·帕西奇

答案 1 :(得分:0)

这实际上是如此简单,令我惊讶的是他们没有正确地记录下来。 在您的存储库中,执行以下操作:

return $this->_em->createQueryBuilder()
    ->select('notification')
    ->from(Notification::class, 'notification')
    // whatever else you need

请注意,从实体管理器而非实体存储库本身创建查询生成器