繁体   English   中英

PHP doctrine 1.2 ORM - 具有类表继承的多态查询

[英]PHP doctrine 1.2 ORM - polymorphic queries with class table inheritance

我正在试验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操作,以组合“威士忌”和“杜松子酒”表的结果集。

这称为多态查询

根据此票证 ,Doctrine 1.x中不提供此功能。 它注定要发布2.0版本。 (另见CTI的 Doctrine 2.0文档)。

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

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

我写了一个(不是生产准备好的)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')

从这里开始有各种各样的变化,比如在子类表中存储所有的酒类数据,并且只在白酒表中存储引用和子类名称。 我最喜欢这个,但是如果你正在聚合公共数据,它将使你不必查询公共字段的每个子类表。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM