【问题标题】:PHP doctrine 1.2 ORM - polymorphic queries with class table inheritancePHP 学说 1.2 ORM - 具有类表继承的多态查询
【发布时间】:2011-03-13 15:57:08
【问题描述】:

我正在试验 PHP 的 Doctrine ORM (v1.2)。我已经定义了一个类“酒”,有两个子类“杜松子酒”和“威士忌”。我正在使用具体继承(大多数文献中的类表继承)将类映射到三个单独的数据库表。

我正在尝试执行以下操作:

$liquor_table = Doctrine_Core::getTable('liquor');
$liquors = $liquor_table->findAll();

最初,我希望 $liquors 是一个包含所有酒的 Doctrine_Collection,无论它们是威士忌还是杜松子酒。但是当我执行代码时,我得到一个空集合,尽管威士忌和杜松子酒数据库表中有几行。根据生成的 SQL,我明白了原因:ORM 查询的是“酒”表,而不是存储实际数据的威士忌/杜松子酒表。

请注意,当我将继承类型切换为列聚合(简单表继承)时,代码可以完美运行。

获取包含所有酒类的 Doctrine_Collection 的最佳方法是什么?

更新

经过更多研究,看起来我期待 Doctrine 在幕后执行 SQL UNION 操作以组合来自“威士忌”和“杜松子酒”表的结果集。

这被称为多态查询

根据this ticket,此功能在 Doctrine 1.x 中不可用。它的目标是 2.0 版本。 (另请参阅 CTI 的 Doctrine 2.0 文档)。

那么根据这些信息,解决这个缺陷的最干净、最有效的方法是什么?切换到单表继承?执行两个 DQL 查询并手动合并生成的 Doctrine_Collections?

【问题讨论】:

    标签: php doctrine class-table-inheritance


    【解决方案1】:

    目前Doctrine唯一稳定有用的继承模式是column_aggregation。我在不同的项目中尝试过其他人。使用 column_aggregation,您可以模仿多态查询。 一般来说,继承在 Doctrine (1.x) 中有点问题。在 2.x 中,这将发生变化,因此我们将来可能会有更好的选择。

    【讨论】:

      【解决方案2】:

      我编写了一个 ORM 的(未准备好生产的)开端,它可以完全满足您一段时间以来的需求。只是为了让我有一个概念证明。我所有的研究都表明你在某种程度上混合了代码和数据(酒表中的子类信息)。

      所以你可以做的是在你的酒类/表类上写一个方法来查询它自己的表。摆脱不必对酒类中的所有子类进行硬编码的最好方法是在其中包含一个包含子类的类名的列。

      如何传播细节完全取决于您。我认为最规范的(如果我在这里错了,任何人都可以纠正我)的方法是将出现在您的酒类中的所有字段存储在酒表中。然后,对于每个子类,都有一个存储与子类类型相关的特定数据的表。 这是您混合代码和数据的地方,因为您的代码正在读取酒表以获取子类的名称以执行连接。

      在我的示例中,我将使用汽车和自行车以及它们之间的一些最小但微不足道的区别:

      Ride
      ----
      id
      name
      type
      
      (1, 'Sebring', 'Car')
      (2, 'My Bike', 'Bicycle')
      
      Bicycle
      -------
      id
      bike_chain_length
      
      (2, '2 feet')
      
      Car
      ---
      id
      engine_size
      
      (1, '6 cylinders')
      

      从这里开始有各种各样的变化,比如将所有酒类数据存储在子类表中,只将引用和子类名称存储在酒类表中。我最不喜欢这个,因为如果您聚合公共数据,它可以让您不必为公共字段查询每个子类表。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-06
        • 2011-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多