资讯专栏INFORMATION COLUMN

Laravel Eloquent中的 懒加载VS即时加载

Keven / 942人阅读

摘要:在本文中,我们将了解中的懒加载和即时加载以及它如何在后台运行。现在所有的房屋数据和在关系表中的数据都同时加载出来了,查询的语句的是使用即时加载时仅执行个查询。总结现在你理解了这个过程,希望它能帮助你理解懒加载和即时加载的用法和基本原理。

Laravel中的Eloquent(ORM)的工作方式很令人惊讶,并提供访问数据库的非常简单的方法。在本文中,我们将了解Laravel Eloquent中的懒加载和即时加载以及它如何在后台运行。

Eloquent 中的关系

第一步我们需要定义模型之间的关系的。在这个例子中,我将使用两个模型,housecity。房子属于一个城市,城市有很多房屋。让我们看看模型 House 的关系:

class House extends Model
{
    protected $fillable = [
        "title", "description", "price"
    ];

    public function city() {
        return $this->belongsTo("AppCity");
    }
}
注意:对于多对一的关系(房子属于一个城市),函数名称是单数。 [public function city()]
class City extends Model
{
    protected $fillable = [
        "name", "code"
    ];

    public function houses() {
        return $this->hasMany("AppHouse");
    }
}
注意:对于一对多关系(城市有很多房屋),函数名称是复数。 [public function houses()]
懒加载
$houses = House::all();

默认情况下,在Eloquent中访问数据是“懒加载”,在上面的代码中,我们获取了所有数据在内部表中,实际执行的SQL查询是:

select * from `houses`

在这一步中,关系表(城市)中的数据还没有被获取,如果我们想访问关系表中的数据,我们可以像这样访问:

foreach ($houses as $house) {
    echo $house->city->name; // 这就是懒加载
}

实际执行的SQL查询是

select * from `cities` where `cities`.`id` = ? limit 1
select * from `cities` where `cities`.`id` = ? limit 1
select * from `cities` where `cities`.`id` = ? limit 1
...

该过程将循环房屋内的所有记录,并为每个循环执行1次查询以获取城市数据,例如我们有20个房屋记录,查询获取关系表中的数据将执行20次+1原始查询获取 房屋数据,查询“延迟加载”的时间是N + 1。

即时加载

有时在应用程序中使用即时加载非常有用,例如,你正在使用Ajax调用数据,在这种情况下,我们必须使用预加载来准备在关系表中包含数据的所有数据,然后再将结果返回给Ajax。 要使用即时加载,只需在获取数据时使用 with 方法。

$houses = House::with("city")->get();

现在所有的房屋数据和在关系表中的数据都同时加载出来了,查询的SQL语句的是

select * from houses
select * from cities where id in (1, 2, 3, 4, 5, ...)

使用即时加载时仅执行2个查询。 正如你可以看到上面的查询,一个查询是在房屋表中获取所有数据,另一个查询是获取城市表中的所有数据,使用IN操作将ID与房屋表中的city_id匹配。

懒加载 和 即时加载

在某些情况下,这对于即时动态加载非常有用,我们可以决定是否需要加载关系表中的数据。

$houses = House::all();

if($isLoad) {
    $houses->load("city"); // 对应 house model中的 city 方法
}

我们可以使用 load 方法在特定条件下加载关系表中的数据。

这一点非常有用,实际中大家可以多试试。

总结

现在你理解了这个过程,希望它能帮助你理解懒加载和即时加载的用法和基本原理。

更多PHP知识,可以前往PHPCasts

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30761.html

相关文章

  • laravel vs lumen 执行对比

    摘要:环境核内存开启性能监控使用生产环境命令进行安装统一执行打印框架执行时间内存最主要差异加载所有文件整理时间线整体执行时间时间改为加载如何动态加载可优化可优化为什么需要复制一份整理时间线整体执行时间时间加载所有文件,差异差异差异差异 环境 centos7 + docker(alpine3.7) 1核 内存2G php7.1.17 开启opcache 性能监控tideways_xh...

    lylwyy2016 评论0 收藏0
  • Laravel核心解读--Database(四) 模型关联

    摘要:为关联关系设置约束子模型的等于父模型的上面设置的字段的值子类实现这个抽象方法通过上面代码看到创建实例时主要是做了一些配置相关的操作,设置了子模型父模型两个模型的关联字段和关联的约束。不过当查询父模型时,可以预加载关联数据。 Database 模型关联 上篇文章我们主要讲了Eloquent Model关于基础的CRUD方法的实现,Eloquent Model中除了基础的CRUD外还有一个...

    gekylin 评论0 收藏0
  • 记一次 Laravel 应用性能调优经历

    摘要:为了一探究竟,于是开启了这次应用性能调优之旅。使用即时编译器和都能轻轻松松的让你的应用程序在不用做任何修改的情况下,直接提高或者更高的性能。 这是一份事后的总结。在经历了调优过程踩的很多坑之后,我们最终完善并实施了初步的性能测试方案,通过真实的测试数据归纳出了 Laravel 开发过程中的一些实践技巧。 0x00 源起 最近有同事反馈 Laravel 写的应用程序响应有点慢、20几个并...

    warkiz 评论0 收藏0
  • 分享 10 个你可能不知道的 Laravel Eloquent 小技巧

    摘要:是一个功能丰富的框架。但是,你无法从官方文档中找到所有可用的功能。例数据库又插入一条为的数据。也很乐意听到你对此的看法和想法。你可以在上找到我。 showImg(https://segmentfault.com/img/remote/1460000017973901?w=800&h=511); Laravel 是一个功能丰富的框架。但是,你无法从官方文档中找到所有可用的功能。以下是一些...

    Simon_Zhou 评论0 收藏0
  • LaravelLaravel 框架关键技术解析·读书笔记(一)

    摘要:判断是否存在构造函数,不存在直接实例化,存在则通过来获取输入函数,并有相应的方法解决依赖参数问题,实现依赖注入。 Laravel 框架关键技术解析·读书笔记(一) 第一章 入口文件 请求访问的入口文件,主要完成几部分工作,分别是: 自动加载函数的添加 服务器实例化与服务注册 路由加载 请求实例化与路由分发 相应生成与发送 其中,自动加载函数用于包含引用文件,改文件是composer...

    CocoaChina 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<