【发布时间】:2012-11-23 09:02:06
【问题描述】:
我正在使用数据映射器模式,我想知道处理与该模式的关系的最佳方法是什么。我花了很多时间在 Google 和 Stack Overflow 中寻找解决方案,我找到了一些,但我仍然对它们并不完全满意,尤其是在我将尝试解释的一种特殊情况下。
我正在使用 PHP,所以我将放置的代码示例都在 PHP 中。
假设我有一个表“team”(id,name)和一个表“player”(id,name,team_id)。这是一个 1-N 的关系。 通过实现 Data Mapper 模式,我们将拥有以下类:Team、TeamMapper、Player 和 PlayerMapper。
到目前为止,一切都很简单。如果我们想从一个团队中获得所有玩家怎么办?
我找到的第一个解决方案是在 Team 类中创建一个 getAllPlayers() 方法,该方法将通过延迟加载和代理来处理该问题。然后,我们可以像这样检索球队的球员:
$players = $team->getAllPlayers();
我找到的第二种解决方案是直接使用 PlayerMapper 并将团队 ID 作为参数传递。比如:
$playerMapper->findAll(array('team_id' => $team->getId()));
但是现在,假设我想显示一个包含所有球队的 HTML 表格,以及一个包含每个球队所有球员的“球员”列。如果我们使用我描述的第一个解决方案,我们将不得不执行一个 SQL 查询来获取球队列表,并为每个球队执行一个查询来获取球员,这意味着 N+1 个 SQL 查询,其中 N 是球队的数量。
如果我们使用我描述的第二种解决方案,我们可以首先检索所有团队 ID,将它们放入一个数组中,然后将其传递给玩家映射器的 findAll 方法,如下所示:
$playerMapper->findAll(array('team_id' => $teamIds));
在这种情况下,我们只需要运行 2 个查询。好多了。但我仍然对这个解决方案不太满意,因为模型中没有描述关系,开发人员必须了解它们。
所以我的问题是:数据映射器模式还有其他替代方案吗?在我给出的示例中,有没有一种好方法可以在 2 个查询中选择所有包含所有球员的球队,并将关系描述到模型中?
提前谢谢你!
【问题讨论】:
标签: php design-patterns orm datamapper