如何用ORM查询?

时间:2013-11-18 02:43:09

标签: kohana kohana-orm kohana-3.3

我使用Kohana几个星期了。我注意到的一件事是Kohana缺少急切的装载(据我所知)。假设我有以下表格。

受试者

id
name

章节

id
subject_id
name

id
chapter_id
name

当用户打开主题页面时,我想显示所有章节和视频。使用ORM,我可以做到

$tutorials = ORM::factory('subject')->where('id','=', 1)->find();

foreach($tutorials as $tutorial) 
{
    $chapters = $tutorial->chapters->find_all();
    foreach($chapters as $chapter) 
    {
        $videos = $chapter->videos->find_all();
    }
}

上面的代码效率不高,因为它会进行太多查询。

我考虑过使用 join 数据库查询构建器,但它们都没有返回模型对象作为结果。我也查看 with(),但看起来它只适用于一对一的关系。

在ORM对象上使用join会返回一个OPM对象,但它不会从连接表中返回数据。

这里最好的选择是什么?我想最小化查询次数,并希望获得ORM对象的结果。无论它是什么,都应该返回教程,章节和视频中的所有专栏。

2 个答案:

答案 0 :(得分:3)

首先,您的代码过多。 ORM方法find()返回1个Model_Subject对象。参见

$chapters = ORM::factory('subject', 1)->chapters->find_all();
foreach($chapters as $chapter) 
{
    $videos = $chapter->videos->find_all();
}

使用DB构建器,您只需提出2个请求。首先得到所有章节ID的数组:

$chapters = DB::select('id')
   ->from('chapters')
   ->where('subject_id', '=', '1')
   ->execute()
   ->as_array(NULL, 'id');

其次 - 通过ID获取所有视频作为Model_Video对象

$videos = DB::select('id')
    ->from('videos')
    ->where('chapter_id', 'IN', $chapters)
    ->as_object('Model_Video') 
    ->execute()
    ->as_array();

答案 1 :(得分:1)

所以我想你想要这样的东西。

$videos = ORM::factory('Video')
    ->join(array('chapters', 'chapter'), 'LEFT')->on('video.chapter_id', '=', 'chapter.id')
    ->join(array('subjects', 'subject'), 'LEFT')->on('chapter.subject_id', '=', 'subject.id')
    ->where('subject.id', '=', $id)
    ->find_all();

考虑一下,如果视频belongs_tobelongs_to主题,请使用with()尝试以下内容:

$videos = ORM::factory('Video')
    ->with('chapter:subject')        // These are the names of the relationships. `:` is separator
                                     // equals $video->chapter->subject;
    ->where('subject.id', '=', $id)
    ->find_all();

通过这样的事情,往往有助于思考“倒退”。您需要有关该主题的视频,因此请先从视频开始,而不是主题。 :)

编辑:第二个功能的缺点是它将预加载所有数据,它可能会更短,但在服务器上更重。除非我需要知道主题和章节,否则我会使用第一个。