2010-03-28 75 views
4

我認爲在Zend Framework中要理解的更難的概念之一是表數據網關模式應該如何處理多表連接。大多數我見過的要求,你根本處理連接使用$ DB-> select()的建議...PHP/Zend Framework:哪個對象會處理複雜的表連接?

Zend DB Select with multiple table joins
Joining Tables With Zend Framework PHP
Joining tables wthin a model in Zend Php
Zend Framework Db Select Join table help
Zend DB Select with multiple table joins

我的問題是:哪個對象最適合處理這種多表選擇語句?我覺得把它放在模型中會破壞類和數據庫表之間的1-1表數據網關模式。然而,把它放在控制器中似乎是錯誤的,因爲控制器爲什麼要處理SQL語句?無論如何,我覺得ZF使得處理來自多個表格的數據集比它需要的難度更大。你可以提供的任何幫助是偉大的...

謝謝!

回答

5

definition,TableData網關只處理一個表。

ZF通過對Zend_Db_Table_Selects進行完整性檢查來強制執行此定義。但是,可以禁用完整性檢查,然後您可以進行連接。只要創建一個方法,你的表類裏面做通過選擇對象像這樣加入:

public function findByIdAndJoinFoo($id) 
{ 
    $select = $this->select(); 
    $select->setIntegrityCheck(false) // allows joins 
      ->from($this) 
      ->join('foo', 'foo.id = bar.foo_id'); 

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

如果你想堅持的定義,你可以使用some sort of Service LayerDataMapper知道如何處理多個表。這些位於Db類和控制器之間。

另一種方法是不使用連接,但是根據需要使用table relationships,然後使用延遲加載相關行集。當然,那不是加入,而是多個查詢。

最後,你仍然可以只使用Zend_Db_Statement and craft your SQL by hand

$stmt = $db->query(
       'SELECT * FROM bugs WHERE reported_by = ? AND bug_status = ?', 
       array('goofy', 'FIXED')); 
+0

謝謝,戈登,這是非常豐富的,但仍然有我的困惑。每次需要執行連接時,打破TableData網關定義似乎很奇怪,這正是RDBMS所能做到的。但隨後引入整個服務層會增加複雜性,看似簡單的問題。似乎要走的路是一個手工製作的聲明,但最好的地方放在哪裏?同樣,我希望它在模型中的某個位置,但是我沒有看到它在特定網關類中的方法,因爲該語句將跨越多個表。 – Thomas 2010-03-29 01:44:43

+0

@Thomas看起來很簡單,但事實並非如此。您可以在您的數據庫中創建視圖或者使用模擬視圖的TDG。如果你在TDG中這樣做,插入將會很困難。只要您的域對象映射1:1到底層數據庫,TDG就可以很好地工作。但他們很少做到(阻抗不匹配),因此使用某種ORM或其他ServiceLayer(http://martinfowler.com/eaaCatalog/serviceLayer.html)在您的模型中的持久層和域對象之間進行調解並不罕見。 – Gordon 2010-03-29 07:06:14