ThinkPHP6模型关联查询的5种高级用法详解
一、嵌套预加载的优化实践
在用户-文章-评论三级关联场景中,传统方式会产生N+1查询问题:
// 低效写法
$users = User::select()->each(function($user){
$user->articles->each(function($article){
$article->comments;
});
});
// 高效写法(三级嵌套预加载)
$users = User::with(['articles.comments'])->select();
性能对比:1000条数据下查询次数从1001次降为3次
二、关联条件过滤技巧
使用闭包实现关联模型的条件筛选:
// 查询有VIP评论的文章
Article::hasWhere('comments', function($query){
$query->where('is_vip', 1);
})->select();
// 带状态的关联预加载
User::with(['articles' => function($query){
$query->where('status', 1)->field('id,title');
}])->select();
三、聚合关联统计实战
实现关联数据的统计查询:
// 统计每个用户的文章数(带条件)
User::withCount([
'articles',
'articles as vip_articles_count' => function($query){
$query->where('is_vip', 1);
}
])->select();
// 获取阅读量最高的作者
User::withSum('articles', 'read_count')
->order('articles_sum_read_count', 'desc')
->find();
四、多态关联开发指南
实现评论同时关联文章和视频:
// 定义多态关联
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
// 查询时自动识别关联类型
$comments = Comment::with('commentable')->select();
// 获取关联模型时会自动返回Article或Video实例
五、关联数据自动写入方案
事务处理中的关联保存:
// 同时保存用户和资料
DB::transaction(function(){
$user = User::create([
'name' => '张三',
'profile' => [
'age' => 25,
'address' => '北京'
]
], ['profile']);
// 自动建立profile关联
$profile = $user->profile;
});
注意事项:需要正确定义模型的hasOne/hasMany关联