需要澄清嵌套模型

时间:2010-09-01 14:03:09

标签: php model-view-controller model nested hierarchy

我需要一个关于如何操作嵌套模型的例子。

我们假设,我们有一些订单管理应用程序和模型:订单,位置,项目。

订单可以包含职位和职位可以包含项目。

问题是:如何处理数据选择?

需要的一些用例:

  • 获取有职位的订单列表 项目(如我的示例代码中)
  • 仅获取订单列表(没有职位和项目)
  • 获取一些统计信息,例如,单个位置中所有项目的总金额

我可以这样做:

class Order_Mapper
{
    public function getOrders($criteria)
    {
        $orders = array(); // Get order list from DB

        foreach($orders as $order)
        {
            $positions = Position_Mapper::getPositionsByOrderId($order->id);

            foreach($positions as $position)
            {
                $order->addPosition($position);
            }
        }

        return $orders;
    }
}

class Position_Mapper
{
    public function getPositionsByOrderId($order_id)
    {
        $positions = array(); // Get position list from DB

        foreach($positions as $position)
        {
            $items = Item_Mapper::getItemsByPositionId($position->id);

            foreach($items as $item)
            {
                $position->addItem($item);
            }
        }

        return $positions;
    }
}

...但这是低效的,因为需要许多SQL查询,一个用于订单选择,然后每个订单一个用于获取位置,然后一个用于每个位置以获取项目。

我对MVC缺乏经验,所以欢迎任何帮助!


关于Doctrine的回应 - 我真的不想学习新的ORM套件,也不介意手工编写SQL查询。我只需要了解如何完成上述任务。

Here是我第二次尝试上面提到的所有用例而没有开销。请看看,告诉我你的想法。代码很简单。

1 个答案:

答案 0 :(得分:0)

在这种情况下,我会使用像Doctrine这样的高级对象关系映射器。然后你可以避免n + 1问题,并使用JOIN的复杂查询,以便一次检索相关数据,而不是选择所有订单,然后在循环中选择每个订单的所有位置等。您可以自己编写映射代码它将数据库结构映射到对象。相反,你只需使用暴露像getAllOrders等方法的存储库,在那里指定你的查询,让Doctrine做繁重的工作。

当您需要更类似于行的方法来进行统计信息等的报表式查询时,Doctrine afaik还支持本机查询,您可以直接访问数据库并使用自定义SQL。

有关该主题的更多信息:

关于stackoverflow的这些主题也有很多问题。这些只是让您入门的一些提示。由于您似乎没有太多关于这些主题的经验,请注意:有一个学习曲线,但它确实值得,因为您可以使用这些技术和模式来驯服复杂的场景。