我需要一个关于如何操作嵌套模型的例子。
我们假设,我们有一些订单管理应用程序和模型:订单,位置,项目。
订单可以包含职位和职位可以包含项目。
问题是:如何处理数据选择?
需要的一些用例:
我可以这样做:
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是我第二次尝试上面提到的所有用例而没有开销。请看看,告诉我你的想法。代码很简单。
答案 0 :(得分:0)
在这种情况下,我会使用像Doctrine这样的高级对象关系映射器。然后你可以避免n + 1问题,并使用JOIN的复杂查询,以便一次检索相关数据,而不是选择所有订单,然后在循环中选择每个订单的所有位置等。您可以自己编写映射代码它将数据库结构映射到对象。相反,你只需使用暴露像getAllOrders等方法的存储库,在那里指定你的查询,让Doctrine做繁重的工作。
当您需要更类似于行的方法来进行统计信息等的报表式查询时,Doctrine afaik还支持本机查询,您可以直接访问数据库并使用自定义SQL。
有关该主题的更多信息:
关于stackoverflow的这些主题也有很多问题。这些只是让您入门的一些提示。由于您似乎没有太多关于这些主题的经验,请注意:有一个学习曲线,但它确实值得,因为您可以使用这些技术和模式来驯服复杂的场景。