2013-06-29 50 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