ThinkPHP6.0关联查询通过模型定义关系(belongsTo/hasOne/hasMany/belongsToMany)并配合with()预加载、join()联查或懒加载实现;with()推荐用于避免N+1问题,支持嵌套与条件预加载;join()返回数组,适合跨表排序筛选;懒加载适用于按需获取,但需防重复查询。

ThinkPHP6.0 中关联查询通过模型的关联定义和链式调用实现,核心是先定义关联关系,再用 with()、join() 或关联方法进行查询。
定义关联关系
在模型类中使用内置关联方法声明关系,如一对一、一对多、多对多:
-
belongsTo(属于):例如文章属于作者,在
Article模型中定义:public function author() { return $this->belongsTo(User::class, 'user_id', 'id'); } -
hasOne / hasMany(拥有一个/多个):例如用户拥有一张资料表或多个文章,在
User模型中:public function profile() { return $this->hasOne(Profile::class, 'user_id', 'id'); }public function articles() { return $this->hasMany(Article::class, 'user_id', 'id'); } -
belongsToMany(多对多):例如文章与标签,需指定中间表:
public function tags() { return $this->belongsToMany(Tag::class, 'article_tag', 'tag_id', 'article_id'); }
使用 with() 预加载关联数据(推荐)
避免 N+1 查询问题,一次性查出主表及关联数据:
- 查文章列表并预加载作者和分类:
Article::with(['author', 'category'])->select(); - 支持嵌套预加载(如作者的头像信息):
Article::with(['author.avatar', 'tags'])->select(); - 带条件预加载(仅加载已启用的标签):
Article::with(['tags' => function ($query) { $query->where('status', 1); }])->select();
使用 join() 进行原生关联查询
适合需要字段合并、排序或条件跨表的场景,返回的是数组而非模型对象:
立即学习“PHP免费学习笔记(深入)”;
- 联查文章和作者用户名:
Article::alias('a')<br> ->join('user u', 'a.user_id = u.id')<br> ->field('a.*, u.username')<br> ->select(); - 注意:join 后不能直接调用模型关联方法,也不走模型事件和自动转换
主动调用关联方法获取数据
适用于已查出主模型后,按需获取关联数据(懒加载):
- 查单个文章后获取作者:
$article = Article::find(1);<br>$author = $article->author;
- 获取关联模型的统计或聚合结果:
$count = $article->comments()->count(); // 查评论数<br>$latest = $article->comments()->order('create_time', 'desc')->limit(1)->find(); - 注意:多次调用可能触发重复查询,建议配合
load()或优先用with()
关联字段命名要与外键一致,模型关联方法名通常用小驼峰;开启严格模式时,字段不存在会报错。调试时可用 getLastSql() 查看生成的 SQL。



















