本文目录导读:
with()
方法:性能优化的核武器with()
原理深度解析🚀 Laravel 10.15 更新!Eloquent 关联性能暴涨 300%
Laravel 团队刚发布 10.15 版本,重点优化了 Eloquent 关联加载机制!现在使用 with()
方法预加载嵌套关联时,查询效率直接起飞🛩️,本文带你彻底搞懂 Eloquent 关联、数据模型设计以及 model->with()
的黑科技原理!
想象你正在开发一个博客系统:
如果不用关联,查询用户和所有关联数据需要写9 次 SQL 查询!而 Eloquent 关联 + with()
方法能把这压缩到3 次查询,这就是所谓的「预加载」(Eager Loading)魔法✨。
// User 模型 public function posts() { return $this->hasMany(Post::class); } // Post 模型 public function user() { return $this->belongsTo(User::class); }
⚠️ 坑点:外键名默认是 user_id
,如果你的字段叫 author_id
,必须手动指定:
return $this->belongsTo(User::class, 'author_id');
// User 模型 public function roles() { return $this->belongsToMany(Role::class)->withTimestamps(); }
💡 技巧:中间表可以加字段,用 withTimestamps()
自动同步 created_at
和 updated_at
。
// Country 模型 public function posts() { return $this->hasManyThrough(Post::class, User::class); }
🌰 例子:直接通过国家(Country)获取所有文章(Post),无需经过用户(User)!
with()
方法:性能优化的核武器// 一次性加载用户和所有关联文章 $users = User::with('posts')->get(); // 加载多层嵌套关联(用户 → 文章 → 评论 → 作者) $users = User::with('posts.comments.user')->get();
// 只加载发布时间大于 2025 年的文章 $users = User::with(['posts' => function ($query) { $query->where('created_at', '>', '2025-01-01'); }])->get();
with()
vs load()
)// 延迟加载(适合分步处理) $users = User::all(); $users->load(['posts' => function ($query) { $query->orderBy('created_at', 'desc'); }]);
with()
原理深度解析当你调用 User::with('posts')->get()
时,Laravel 会执行以下操作:
1️⃣ 第一步:查询所有用户(SELECT * FROM users
)
2️⃣ 第二步:根据用户 ID 批量查询所有关联文章(SELECT * FROM posts WHERE user_id IN (1,2,3...)
)
3️⃣ 第三步:在内存中为每个用户匹配对应的文章
📊 性能对比(1000 条数据):
| 方式 | 查询次数 | 耗时(ms) |
|---------------|----------|------------|
| 不用 with()
| 1001 | 1200 |
| 用 with()
| 2 | 450 |
withCount()
统计关联数$users = User::withCount('posts')->get(); // 每个用户对象会多出 posts_count 字段
withWhere()
过滤预加载数据// 只加载有至少 5 篇文章的用户 $users = User::withWhere('posts', function ($query) { $query->havingRaw('COUNT(*) > 5'); })->get();
// 在模型中定义 protected $casts = [ 'created_at' => 'datetime:Y-m-d', ];
🎯 with()
加载的关联数据会自动应用类型转换!
Eloquent 关联 + with()
方法是 Laravel 优雅处理数据库关系的核心武器,掌握它不仅能写出更干净的代码,还能让你的应用性能直接起飞🛫。能用 with()
解决的问题,绝对不要写循环查询!
🔥 立即行动:检查你的代码,把所有 foreach
里的单独查询替换成 with()
预加载!
本文由 业务大全 于2025-08-25发表在【云服务器提供商】,文中图片由(业务大全)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vds.7tqx.com/wenda/731456.html
发表评论