$_referenceMap 与 Zend_Db_Table_Abstract 的关系创建了太多查询

发布于 2024-09-19 06:30:13 字数 2957 浏览 10 评论 0原文

这是我第一次在应用程序中使用 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;
    }
}

class Application_Model_DbTable_ShoppingCart extends 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 个商品时,数据库分析器会显示超过 60 个查询 (WHOA) 来查看购物车商品(显示所有四个表中的信息 - 产品名称、单位描述、分销商名称)。 对于每个商品,它都会查询 shopping_cart,然后查询产品表,然后查询产品单位,然后查询 distributioner_table。

有没有一种方法可以让它作为一个查询运行,通过 Zend_Db_Table_Abstract 关系连接所有表?
我是否必须重新在 Application_Model_ShoppingCart 类中使用数据库适配器?

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

预先感谢您的建议,我喜欢 Zend Framework,但鉴于人们谈论使用模型的不同相互冲突的方式,模型对我来说仍然很难理解。

This is my first time using Zend Framework for an application and i don't know if I completely have by head around Models.

I have four tables: shopping_cart, product, product_unit, distributor.
shopping cart has an cart_id, product_id, unit_id and dist_id (shopping cart joins on the other tables with their corresponding id).

Before Zend I would create a class like this:

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);
}

One query to get all the information from the joined tables.

When I set up the relationship mapping in Zend_Db_Table_Abstract:

My Shopping Cart Model:

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;
    }
}

class Application_Model_DbTable_ShoppingCart extends 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);
}

}

In my controller:

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

IN my view :

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');
}

when I have ten items in my cart the db profiler shows over sixty queries (WHOA) to view the cart items ( information across all four tables are displayed - product name, unit description, distributor name).
For each item it queries the shopping_cart, then querys the product table, then the product unit, then the distributor_table.

Is there a way to have this run as one query joining all the tables via Zend_Db_Table_Abstract relationships?
Will I have to go back to using db adapter in the my Application_Model_ShoppingCart class?

I want to abstract all data access to the table models (Application_Model_DbTable_ShoppingCart) and not have the Application_Model_ShoppingCart tied to a db handler.

Thanks in advance for advice, I love the Zend Framework but models are still hard for me to understand given the different conflicting ways people talk about using them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倥絔 2024-09-26 06:30:13

简而言之,不,不幸的是,不可能在单个查询中获取一组表行及其关系。

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

但至少,您可以使用 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);
   }
}

In short, no, unfortunately it's not possible to get a set of table rows together with their relationships in a single query.

It's just that all methods dealing with relationships are defined for a row, not for a table.

But at least, you can form your sql with Zend_Db_Table_Select instead of writing it all manually.

Upd: Your code for fetching ShoppingCarts, in my opinion, should belong to the table (DbTable_ShoppingCart). So, the code you provided in the beginning could be transformed to the following:

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);
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文