当前位置:  开发笔记 > 编程语言 > 正文

Laravel 5:默认情况下Eloquent急切加载吗?

如何解决《Laravel5:默认情况下Eloquent急切加载吗?》经验,为你挑选了1个好方法。

我有这个结构:

学校 - > hasMany - > Classes

所以当我尝试下面的代码时 artisan tinker

App\School::with('schoolclasses')->find(2283)->schoolclasses;

我可以毫无问题地获得课程.

但是当我尝试没有使用时,我仍然可以得到相同的结果而没有问题:

App\School::find(2283)->schoolclasses;

是否Eloquent急于加载?如果是这样,如何禁用它?



1> Thomas Kim..:

不,Laravel默认情况下并不急于加载.让我们一步一步来.让我们->schoolclasses;暂时忽略.

App\School::with('schoolclasses')->find(2283);

这将两次查询数据库.首先,它将获得School2283的主键.然后,它将立即查询数据库并获得所有相关的schoolclasses.

App\School::find(2283);

这只会查询一次数据库.它只会得到School.到目前为止还没有急切的加载.如果您调试并跟踪数据库查询,您将看到这只会查询数据库一次,而急切加载将查询它两次.

当您尝试访问该schoolclasses->schoolclasses;,一切实际工作.那你为什么得到同样的结果呢?它有点欺骗性,但它不一样.当您尝试访问时schoolclasses,Laravel将检查它是否已被急切加载.如果是这样,它将返回该集合schoolclasses.没有查询.它只是立即返回它们.但是,如果您没有急于加载它们,Laravel将在现场查询数据库并获取schoolclasses.最终,对于这个特定的例子,你会得到相同的结果,但是当你查询数据库时会有所不同.

然而,这实际上是热切加载的主要好处的一个不好的例子.

预先加载的主要好处是缓解N + 1查询问题.假设您想要获得5所学校及其所有课程.如果没有急切的加载,这就是你要做的:

$schools = School::take(5)->get();

foreach ($schools as $school)
{
    $schoolclasses = $school->schoolclasses;
}

对于这样一个简单的任务,总共有6个查询.我在下面添加了评论,以了解查询的来源:

$schools = School::take(5)->get(); // First query

foreach ($schools as $school)
{
    // For each school, you are querying the database again to get its related classes.
    // 5 schools = 5 more queries
    $schoolclasses = $school->schoolclasses;
}

但是,如果您急于加载所有内容,则只有两个查询:

// Two queries here that fetches everything
$schools = School::with('schoolclasses')->take(5)->get();

foreach ($schools as $school)
{
    // No more queries are done to get the classes because
    // they have already been eager loaded
    $schoolclasses = $school->schoolclasses;
}

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有