Laravel Eloquent两次相同find查询的对象创建数与数据库查询次数问题
Laravel Eloquent find方法执行原理解答
首先修正示例代码的笔误:第二行Flight:find(1)存在语法错误,正确写法为Flight::find(1),以下分析基于修正后的代码展开。
数据库查询次数
默认Laravel配置下,总共会执行2次数据库查询,两次执行的SQL完全一致:
select * from `flights` where `id` = 1 limit 1
原理说明
- Laravel Eloquent默认未开启全局查询缓存和身份映射(Identity Map)机制,每次调用
find方法都会生成独立的查询请求发送到数据库。 - 仅当显式使用查询缓存(如调用
cache()方法、安装第三方身份映射扩展)时,才会复用第一次的查询结果,仅执行1次查询。
创建对象数量
默认配置下,总共会创建2个独立的Flight模型对象。
原理说明
- 每次
find方法拿到数据库返回的查询结果后,都会调用newModelInstance()方法新实例化一个Flight类的对象,再把查询到的属性填充到新对象中返回。 - 哪怕两次查询返回的数据集完全一致,得到的也是两个不同的对象实例,修改
$a的属性不会同步到$b,通过$a === $b判断会返回false。
例外情况
如果项目中集成了Eloquent的身份映射功能,第一次查询后会把主键对应的模型实例存到内存中,第二次调用find(1)时会直接返回已经实例化好的对象,此时只会创建1个对象,$a === $b返回结果为true。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

