我最近开始使用Zend Framework(1.8.4),提供管理工具来查看购物车网站的订单。
我想要做的是从单个数据库结果行有效地创建多个模型(Zend_Db_Table_Row_Abstract
)对象。
关系很简单:
订单有一个客户(外键order_custid=customer.cust_id
);
客户有很多订单。
加载订单很简单。使用此处记录的方法:
Modeling objects with multiple table relationships in Zend Framework
......然后我可以抓住每个客户。
foreach ($orderList as $o)
{
cust = $o->findParentRow('Customers');
print_r ($cust); // works as expected.
}
但是当你加载一长串订单时 - 比方说40个或更多,一个页面 - 这很慢。
接下来我尝试了JOIN:
$custTable = new Customers();
$orderTable = new Orders();
$orderQuery = $orderTable->select()
->setIntegrityCheck(false) // allows joins
->from($orderTable)
->join('customers', 'cust_id=order_custid')
->where("order_status=?", 1); //incoming orders only.
$orders = $orderTable->fetchAll($orderQuery);
这给了我一个订单对象数组。 print_r($orders)
显示每个列都包含我希望在受保护成员中使用原始字段名称order_ *和cust _ *的列列表。
但是如何从我在每个Order对象中找到的cust_ *字段创建一个Customer对象?
foreach ($orders as $o) {
$cols = $o->toArray();
print_r ($cols); // looks good, has cust_* fields...
$cust = new Customer(array( 'table' => 'Customer', 'data' => $cols ) );
// fails - $cust->id, $cust->firstname, etc are empty
$cust->setFromArray($cols);
// complains about unknown 'order_' fields.
}
有没有什么好方法可以从连接的行同时创建Order和Customer对象?或者我必须在没有表网关的情况下运行查询,获取原始结果集,并将每个字段逐个复制到新创建的对象中?
答案 0 :(得分:1)
我使用此方法将数据库行字段分配给对象。我使用setter方法,但这也可能只用于对象的属性。
public function setOptions(array $options){
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
答案 1 :(得分:1)
Zend_Db
没有提供方便的方法来执行此操作。
假设,对于从多个表派生的行使用 Facade 模式是很好的。 facade类将跟踪哪些列属于每个相应的表。当您使用setFromArray()
方法设置单个字段或整个字段时,Facade将知道如何将字段映射到每个表的Row对象,并将UPDATE
语句应用于表(s受影响。
或者,您可以通过继承Zend_Db_Table_Row_Abstract
来解决未知字段的问题,更改__set()
行为以静默忽略未知列而不是抛出异常。
您不能拥有OO接口来执行SQL可以执行的所有操作。在沙子中必须有一些线路,您可以在其中确定已经涵盖的一组合理的常见案例,并且应该使用SQL来完成任何更复杂的事情。