2013-06-29 44 views
3

我正在尋找關於如何在將對象集合保存到數據庫時使用封裝的最佳實踐建議。封裝與數據庫性能

例如,您需要堅持擁有產品集合的分銷商。如果您繼續封裝並且不要在分發服務器類中混淆與產品表相關的數據庫內容,那麼您需要對數據庫進行太多命中以便將每個產品保存在循環中。該代碼是這樣:

class Distributor { 
    private $products; 
    function save() { 
    foreach ($products as $prod) { 
     // 10000 products = 10000 hits to the DB! Instead of only one! 
     $prod->save(); 
    } 
    } 
} 

在另一方面,如果你想優化查詢和做多行INSERT /中的insertUpdate你可以做更復雜的東西是這樣的:

class Distributor { 
    private $products; 
    $query = $dao->getInsertUpdateQueryInstance(); 
    foreach ($products as $prod) { 
    // Much extra code for implementing such an encapsulation. 
    $query->addRow($prod->getRow()); 
    } 
    $query->execute(); 
} 

這意味着你需要用addRow()函數編寫你的DAO層。

我看到的第三種可能性是在Product類中創建一個靜態數組,但是這打破了關注的邏輯分離。現在,產品列表保持在同一產品類別中,而不是與其分銷商相關。

class Distributor { 
    // I'm a distributor and I have nothing to do... 
} 
class Product { 
    private static $products; 
    function save() { 
    foreach (self::products as $prod) { 
     // add row 
    } 
    // persist 10000 rows 
    } 
} 

封裝,但很醜!如果你有幾個經銷商呢?所有產品將保持在同一陣列中?

是否有一些非過度複雜的方法來實現這一點? ORM是唯一的出路嗎?

回答

1

爲您的分銷商編寫特定的DAO沒有任何問題。第二種解決方案很好,而第三種解決方案不應該被考慮。靜態不好。

乾杯

+0

感謝您的回覆!每個實體都有特定的DAO意味着兩個知道實體內部的類而不是一個,我說得對嗎?可維護性不好嗎?爲什麼靜態如此糟糕?如何編寫用於保存實例的靜態方法('Product :: save($ products)')和類方法('$ this-> save()')來保存實例?在這種情況下也是靜態的嗎? – bandolero

+0

是的,這就是我對特定道的意思。如果你不想讓這個道具知道這個類的私人機制,那麼你可以使用訪問者模式。對於靜態的東西,我建議你只將它用於橫向事件,例如記錄器等等。例如,當你改變全局域時靜態是不好的。這通常會導致可維護性問題,並行化時出現問題等等。 – David