2011-03-27 69 views
0

我正在將原始PHP代碼遷移到CakePHP並且存在一些問題。由於我在查詢ORM轉換時遇到很大問題,我暫時使用原始SQL。一切都很好,但我遇到了難看的代碼,並不知道如何使它變得美麗。我製作了DealersController並添加了function advanced($condition = null)(它將通過參數1-15和69從AJAX中調用)。功能看起來像:在控制器中添加CakePHP查詢

switch ($condition) { 
    case '1': 
    $cond_query = ' AND ((d.email = \'\' OR d.email IS NULL))'; 
    break; 
    case '2': 
    $cond_query = ' AND (d.id IN (SELECT dealer_id FROM dealer_logo)'; 
    break; 
    // There are many cases, some long, some like these two 
} 

if($user_group == 'group_1') { 
    $query = 'LONG QUERY WITH 6+ TABLES JOINING' . $cond_query; 
} elseif ($user_group == 'group_2'){ 
    $query = 'A LITLE BIT DIFFERENT LONG QUERY WITH 6+ TABLES JOINING' . $cond_query; 
} else { 
    $query = 'A LITLE MORE BIT DIFFERENT LONG QUERY WITH 10+ TABLES JOINING' . $cond_query; 
} 

// THERE IS $this->Dealer->query($query); and so on 

所以..當你看到代碼看起來很醜。我有兩個變種:

1)退出查詢添加併爲每個條件製作模型方法,然後這些條件分離到函數。但是這不是DRY,因爲主要的3個大問題幾乎是一樣的,如果我需要改變一個東西 - 我將需要改變16個以上的查詢。 2)使小的可重用模型方法/查詢從DB小塊數據中獲得,然後不使用原始SQL,而是使用方法。這會很好,但表現會很低,我需要儘可能高。

請給我建議。謝謝!

回答

0

如果」關心CakePHP如何爲每個連接的表進行數據庫查詢,您可能會發現Linkable行爲可以幫助您減少查詢的數量(連接是一個表上的簡單關聯)。

否則,我發現在模型級創建簡單的數據庫查詢方法以獲取較小的信息,然後再將它們組合起來是一種好方法。它允許你清楚地描述你的代碼(通過內聯文檔)。如果您可以遷移到使用CakePHP的find方法而不是原始查詢,那麼您將使用conditions數組語法。所以你可以通過一種方法解決你的問題,就是在你的Model類上有公共函數,這些函數將適當的條件附加到輸入的條件數組中。例如:

class SomeModel extends AppModel { 
    ... 
    public function addEmailCondition(&$conditions) { 
     $conditions['OR'] = array(
      'alias.email_address' => null, 
      'alias.email_address =' => '' 
     ); 
    } 
} 

你會調用這些函數來建立一個大的conditions數組,然後你可以用它來檢索您從您的控制器需要的數據(或從模型中,如果要包含所有的模型層)。請注意,在上面的示例中,conditions數組正在通過引用傳遞,因此可以對其進行編輯。還要注意,數組中現有的任何'OR'條件都將被這個函數覆蓋:如果要將新條件與現有條件合併,您的真正解決方案必須更加明智。

不要擔心'假設'性能問題 - 如果您嘗試過查詢並且速度太慢,那麼您可以擔心如何提高性能。但對於初學者來說,儘可能乾淨地編寫代碼。

您還可能想要考慮將function advanced()調用拆分爲多個按其condition查詢的相似性分組的控制器操作。

最後,如果您還沒有將其檢出,請參閱本書的關於從模型中檢索數據的條目。可能有一些你以前從未見過的技巧:http://book.cakephp.org/view/1017/Retrieving-Your-Data

+0

所以..首先感謝Linkable - 我讀到它並認爲它非常有幫助! – Orbitum 2011-03-28 10:55:24

+0

第二個 - 你提供一個函數在模型'find_big_query()'和一個小的函數'add_something_tofunction_find_big_query()'?也許在模型公共變量'additional_query_string'並添加控制器添加?什麼是「最好的方式?」 – Orbitum 2011-03-28 10:58:42

+0

對於如何在不瞭解數據庫模式的情況下如何分解查詢,我無法做出正確的建議;你能否更具體一些? – tokes 2011-03-29 20:44:48

0

如果查詢的底座部分是一樣的,你可以有一個函數生成查詢部分,然後用其他的小功能,附加不同的地方條件等

+0

所以你認爲這是一個好方法? 「最好的辦法」? – Orbitum 2011-03-28 10:52:53

+0

不,我認爲最好的辦法是擺脫查詢和使用Cake函數,但如果你沒有時間,那麼至少可以劃分代碼:) – 2011-03-28 13:30:35

+0

所以...那麼最好的方法是是要使用Linkable(在需要的地方)並且使用model-> find()方法而不是查詢,並且在每個switch :: case中調用此方法?這將是最好的方式? – Orbitum 2011-03-28 14:54:05