MVC面向对象技术 - 如何最小化查询并保持灵活性?

时间:2009-09-25 21:10:14

标签: php model-view-controller design-patterns oop kohana

我在PHP(Kohana)中使用了一个有针对性的MVC框架,并将一些技术混合在一起以完成工作。问题是我不确定如何在不调用每页大量查询的情况下保持清洁。

为了说明我的例子,我想我正在设计像网站一样的堆栈溢出:

我有问题的模型类(question_model)以及问题查找器的模型类(question_finder_model)。

question_model主要只包含存储问题数据的变量,答案对象的数组和一些工厂方法。类似的东西:

class question_model {
    public $question_id,$question_title,$question_body,$answers = array();    
}

问题查找器容器中包含一组question_model对象以及一组问题ID。 id数组由类中的find方法填充,并由其他方法使用。类似的东西:

class question_finder_model {
    private $question_ids = array();
    public $questions = array() ;   //

    function public find_questions () {
        // executes some SQL to find a list of projects
        // Create a new question_model object for each question and store in $questions
        // for each of these questions store the id in $questions_ids
    }
    function public get_answer_info () {
       // using all the question ids stored in $question_ids:
       // find information about the answers
     }
}

所以我对所有模型使用此方法,例如我的用户模型将包含一组问题对象。

问题是它很难处理,例如我的问题包含很多答案,每个答案都可以包含很多评论等等。如何在不进行多次查询的情况下填充所有这些对象。我的意思是简单的方法是迭代我的问题对象数组并调用存储在问题类中的函数,该函数获取该对象的答案信息。但那时我会每页调用10或100个查询。

我很抱歉,如果这个问题很难说清楚,因为这个问题很难说清楚。任何帮助都是值得欣赏的,因为我的整个模式都是有缺陷的。

3 个答案:

答案 0 :(得分:3)

你在这里表达的是最常见的前提问题之一 与天真的ORMappers。 生成多个查询。

您可以在此处阅读有关问题的准确说明:ORMs Done right: (DBA Gripe #3: hidden expensive actions)

基本上问题是你需要多次查询:

foreach ($questions in $site) {
 foreach ($question as $questions) {
    foreach ($answer in $question){
       foreach ($comment in $answer) {
         echo "$site->title, $question->title, $answer->title, $comment->title";
       }
    }
 }

}

它变得非常慢,非常快。

您需要做的是使用正确的连接获取一个查询中的所有信息。 然后填充你的对象。

在一些文章中查找建议的实现: Class :: ReluctantORM - 强制预取

最后不要试图让每个案例都正确。关系模型和对象模型“阻抗不匹配”不是解决的问题。所以不要试图自己完美地解决它。毕竟Object-Relational Mapping is the Vietnam of Computer Science

答案 1 :(得分:1)

它与PHP的关系并不比SQL那么多。

要获取问题的答案列表(包括评论),您可以按问题ID获取所有答案。然后,将所有答案ID收集到一个数组中,并获取该数组中具有答案ID的所有注释。

这是三个问题。您只需要确定哪些评论属于代码中的哪个答案 - 如果您按答案ID对评论进行排序,则可以更快地进行评论,等等。

您还可以使用memcached,文件或其他内容缓存内容,这样可以加快速度。

当然,从这样的结构构建对象可能比仅按查询更复杂,但这只是你需要做的事情。

答案 2 :(得分:0)

Jani Hartikainen总结得很好,我想提一下其他的东西。

  

当你学习OOP时,   一切都开始像一个   对象

虽然确实可以将所有内容声明为类并将其视为对象,但您不必这样做。在您的示例中,可能更容易被视为海量数据操作,而不是处理单个问题/答案/评论对象。

从这个角度来看,你可能会想出像Jani一样的解决方案。

相关问题