2011-07-08 35 views
7

我在Zend Framework中唱數據映射器模式。目前爲止,這種方法運行良好,但現在我已經到了需要你的幫助/意見的地步。因此,讓我們先從代碼:數據映射器模式:來自服務層的配合物查詢

我們得到了一個表,幾個人:

CREATE TABLE `persons` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `age` int(3) NOT NULL, 
    `haircolor` varchar(20) DEFAULT NULL, 
    PRIMARY KEY (`id``), 
); 

現在我儘量選擇所有的人,有棕色的頭髮。我用下面的方法在ServiceLayer

public function getPeopleByHaircolor($hair) { 
    return $this->getMapper()->fetch('haircolor = ?', $hair); 
} 

在映射的方法是這樣的:

public function fetch($condition, $value) { 
    $resultSet = $this->getTable()->fetchAll($this->getTable()->select()->where($cond, $value)); 
    $entries = array(); 

    foreach($resultSet as $row) { 
    $entry = new Default_Model_Person(); 
    $entry->id = $row->id; 
    $entry->name = $row->name; 
    [...] 
    } 
    return $entries; 
} 

我覺得我按照數據映射模式與此方法...


現在的問題:

我wa nt來選擇有棕色頭髮且年齡小於20歲的人員。 那麼我該怎麼做?我嘗試:

public function getTeens($hair) { 
    $rows = $this->getMapper()->fetch('haircolor = ?', $hair); 
    $return = array(); 
    foreach($rows as $row) { 
    if((int)$row->age < 20) $return[] = $row; 
    } 
    return $return; 
} 

但是,如果你得到更多的變量,如「人與棕色的頭髮,比20yrs年輕,名稱爲‘富吧’」,我需要更多的方法和/或foreach循環。


我的問題:

你將如何在數據映射模式做到這一點?如果我做一個像$ serviceLayer-> mapper-> table-> qry('SELECT ...')的本地SQL查詢,這是否破壞了數據映射器模式? 我不喜歡那些額外的foreach循環,感覺就像我做錯了什麼,所以我寫了這個問題。

回答

6

事實上,對於兩種情況,在迭代時不宜過濾一個條件,然後過濾另一個條件。它讓你沒有兩種以上的條件明確的方法。實施分頁適配器變得相當混亂。

在我看來,問題是您的映射器fetch()方法支持只允許一個條件。所以:

  1. 修改簽名以支持一系列條件。

  2. 或者,您可以創建一個單獨的映射器的方法對每個增強提取方法,例如:fetchByHairAndAge($hair, $age)

+8

第二個選項是可取的,因爲允許搜索任何條件導致域邏輯泄漏到控制器中,並且需要關於類之外的db結構的知識。第二個選項也明確定義了API。 –

+0

@Tomas:的確如此。恰好解釋道。 +1 –

+0

感謝您的建議! –

1

在我與數據映射器有限的經驗,我已經找到了下面的方法工作得很好迄今我所遇到的情景:

public function getPeopleByHaircolorAndAge($haircolor, $age, $limit=null, $offset=null) 
{ 
    $people = new PersonCollection; 
    $people->filterByHaircolor($haircolor); 
    $people->filterByAge($age); 
    $people->setLimit($limit); 
    $people->setOffset($offset); 

    $personCollectionMapper = new PersonCollectionMapper; 
    $personCollectionMapper->fetch($people); 

    return $people; 
} 

通過實例域對象首先我必須設置過濾器和其他變量的數據映射器可以從對象中讀取的選項時,它被注入映射器。

對我來說,與擁有多個返回域對象的映射器方法相比,這是迄今爲止的優越方法。

+0

如果我需要添加更多的條件,我將不得不添加一個新的獲取.....方法,有許多參數,它不是很好可讀,有重複的身體。 –