需要澄清嵌套模型
我需要一个有关如何操作嵌套模型的示例。
假设我们有一些订单管理应用程序和模型:订单、位置、项目。
订单可以包含头寸,头寸可以包含项目。
问题是:如何处理数据选择?
需要的一些用例:
- 获取具有头寸的订单列表和 项目(如我的示例代码中)
- 仅获取订单列表(没有职位和项目)
- 获取一些统计数据,例如单个职位中所有项目的总数
我可以这样做:
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 查询。我只需要知道如何完成上述任务。
这里是我第二次尝试在没有开销的情况下完成上述所有用例。请看一下并告诉我您的想法。代码非常简单。
I need an example on how to operate on nested models.
Let's assume, we have some order management application and models: Order, Position, Item.
Order can contain Positions and Positions can contain Items.
The question is: how to handle data selection?
Some use cases that is needed:
- Get list of Orders with Positions and
Items (like in my example code) - Get only list of Orders (without Positions and Items)
- Get some statistics, for example, total amount of all Items in single Position
I can do something like that:
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;
}
}
... but this is inefficient because there is many SQL queries needed, one for order select, then one for each Order to get Positions and then one for each Position to get Items.
I'm pretty inexperienced in MVC so any help is welcome!
In response about Doctrine - I really didn't want to learn new ORM suite, nor I don't mind writing SQL queries by hand. I just need the idea how to accomplish aforementioned tasks.
Here is my second try to do all of the use cases mentioned above without overhead. Please, take a look and tell me your thoughts. Code is very simple.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这种情况下,我会使用高级对象关系映射器,例如 Doctrine。然后,您可以避免 n+1 问题,并使用 JOIN 进行复杂查询,以便立即检索相关数据,而不是选择所有订单,然后循环选择每个订单的所有位置等。您无需自己编写映射代码它将数据库结构映射到对象。相反,您只需使用公开 getAllOrders 等方法的存储库,在那里指定您的查询并让 Doctrine 完成繁重的工作。
当您需要一种更像行的方法来进行报告式查询以进行统计等时,Doctrine afaik 还支持本机查询,您可以直接访问数据库并使用自定义 SQL。
有关该主题的更多信息:
stackoverflow 上也有很多关于这些主题的问题。这些只是帮助您入门的一些提示。由于您似乎在这些主题上没有太多经验,因此请注意:有一个学习曲线,但这确实值得,因为您甚至可以使用这些技术和模式来驾驭复杂的场景。
In a case like this I would use an advanced object relational mapper like Doctrine. Then you can avoid the n+1 problem and use complex queries with JOINs in order to retrieve related data at once instead of selecting all orders and then in a loop select all positions for each order etc. You are freed from writing the mapping code yourself which maps the database structure to objects. Instead you just use Repositories that expose methods like getAllOrders etc. specify your queries there and let Doctrine do the heavy lifting.
When you need a more row-like approach for report-style queries for statistics etc. Doctrine afaik also supports native queries where you go directly to the database and use custom SQL.
Some more information on that topic:
There are quite a few questions on these topics on stackoverflow, too. These are just a few hints to get you started. As you don´t seem to have much experience on these topics, be warned: there is a learning curve, but it´s really worth it as you can tame even complex scenarios with these technologies and patterns.