$ _referenceMap与Zend_Db_Table_Abstract的关系会产生太多查询

时间:2010-09-16 20:47:05

标签: zend-framework zend-db zend-db-table

这是我第一次在应用程序中使用Zend Framework,我不知道是否完全依赖于模型。

我有四张桌子:shopping_cart,product,product_unit,distributor。 购物车有一个cart_id,product_id,unit_id和dist_id(购物车加入其他表及其相应的ID)。

在Zend之前我会创建一个这样的类:

class ShoppingCart
{
function getItems()
{
$sql ="select * from shopping_cart, product, product_unit, distributor 
where 
shopping_cart.product_id = product.id AND
shopping_cart.unit_id = product_unit.id AND  
shopping_cart.dist_id = distributor.id AND
cart_id = xxx";

$items = $this->db->getAll($sql);
}

从查询表中获取所有信息的一个查询。

当我在Zend_Db_Table_Abstract中设置关系映射时:

我的购物车型号:

class Application_Model_ShoppingCart
{
    function __construct()
    {
        $this->ShoppingCartTable = new Application_Model_DbTable_ShoppingCart();
    }

    function getItems()
    {
        $cart_items = $this->ShoppingCartTable->getItems($this->GetCartId());
        return $cart_items;
    }
}

类Application_Model_DbTable_ShoppingCart扩展了Zend_Db_Table_Abstract {

protected $_name = 'shopping_cart';

protected $_rowClass = 'Application_Model_DbTable_ShoppingCart_Item';

protected $_referenceMap    = array(
    'Product' => array(
        'columns'           => 'product_id',
        'refTableClass'     => 'Application_Model_DbTable_Product',
        'refColumns'        => 'id'
        ),
    'Distributor' => array(
        'columns'           => 'dist_id',
        'refTableClass'     => 'Application_Model_DbTable_Distributor',
        'refColumns'        => 'id'
        ),
    'Unit' => array(
        'columns'           => 'unit_id',
        'refTableClass'     => 'Application_Model_DbTable_ProductUnit',
        'refColumns'        => 'id'
        )
);

public function getItems($cart_id)
{
    $where = $this->getAdapter()->quoteInto('cart_id = ?', $cart_id);

    return $this->fetchAll($where);
}

}

在我的控制器中:

$this->_shoppingCartModel = new Application_Model_ShoppingCart();
$items = $this->_shoppingCartModel->getItems();

在我看来:

foreach($this->items AS $item) 
{
    $item_product = $item->findParentRow('Application_Model_DbTable_Product');
    $item_dist = $item->findParentRow('Application_Model_DbTable_Distributor');
    $item_unit = $item->findParentRow('Application_Model_DbTable_ProductUnit');
}

当我的购物车中有10个项目时,db profiler会显示超过60个查询(WHOA)以查看购物车项目(显示所有四个表格中的信息 - 产品名称,单位描述,经销商名称)。 对于每个项目,它查询shopping_cart,然后查询产品表,然后是产品单元,然后是distributor_table。

有没有办法让这个运行作为一个查询通过Zend_Db_Table_Abstract关系连接所有表?
我是否必须在我的Application_Model_ShoppingCart类中使用db adapter?

我想抽象对表模型(Application_Model_DbTable_ShoppingCart)的所有数据访问,而不是将Application_Model_ShoppingCart绑定到db处理程序。

提前感谢您的建议,我喜欢Zend Framework,但鉴于人们谈论使用它们的不同方式,我仍然很难理解模型。

1 个答案:

答案 0 :(得分:1)

简而言之,不幸的是,不可能在单个查询中将一组表行与它们的关系一起获取。

只是处理关系的所有方法都是为行定义的,而不是为表定义的。

但至少,您可以使用Zend_Db_Table_Select形成您的SQL,而不是手动编写。

更新:在我看来,您获取ShoppingCarts的代码应该属于表格(DbTable_ShoppingCart)。因此,您在开头提供的代码可以转换为以下内容:

class Application_Model_DbTable_ShoppingCart extends Zend_Db_Table_Abstract {
   public function getItem($cart_id) {
      $select = $this->select()
                     ->from( array('sc' => 'shopping_cart'), array(Zend_Db_Select::SQL_WILDCARD) )
                     ->join( array('p' => 'product'), 'sp.product_id = p.id', array(Zend_Db_Select::SQL_WILDCARD) )
                     ->join( array('pu' => 'product_unit'), 'sp.unit_id = pu.id', array(Zend_Db_Select::SQL_WILDCARD) )
                     ->join( array('d' => 'distributor'), 'sp.dist_id = d.id', array(Zend_Db_Select::SQL_WILDCARD) )
                     ->where('sp.cart_id = ?', $cart_id)
                     ->setIntegrityCheck(false);
      return $this->fetchAll($select);
   }
}