答案:ThinkPHP通过模型定义关联关系实现多表查询,支持一对一、一对多等类型,使用with预载入避免N+1问题,可嵌套条件查询,也支持动态延迟加载及多重关联预载入,提升代码清晰度与查询效率。
ThinkPHP 的 ORM 关联查询通过模型之间的关系定义,实现多表数据的自动关联读取。使用时需先在模型中定义关联方法,再通过预载入或动态调用方式获取关联数据。
1. 定义关联关系
在模型类中通过方法声明与其他模型的关系。常见的关联类型包括:一对一、一对多、 belongsTo、hasMany 等。
示例:用户与文章的一对多关系
// app/model/User.php class User extends Model { // 获取该用户的所有文章 public function articles() { return $this->hasMany(Article::class, 'user_id', 'id'); } } // app/model/Article.php class Article extends Model { // 获取文章所属用户 public function user() { return $this->belongsTo(User::class, 'user_id', 'id'); } }
参数说明:
立即学习“PHP免费学习笔记(深入)”;
- 第一个参数:关联模型类名
- 第二个参数:外键字段(当前表指向对方表的字段)
- 第三个参数:主键字段(对方表的主键)
2. 使用预载入查询(推荐)
避免 N+1 查询问题,使用 `with` 预先加载关联数据。
// 查询所有用户,并加载其文章列表 $users = User::with('articles')->select(); foreach ($users as $user) { echo $user->name; foreach ($user->articles as $article) { echo $article->title; } }
支持嵌套预载入:
“`php User::with([‘articles’ => function($query) { $query->where(‘status’, 1); }])->select(); “`
3. 延迟加载(动态调用)
在需要时才加载关联数据,适用于个别场景。
$user = User::find(1); $articles = $user->articles; // 自动触发查询
也可手动调用:
“`php $articles = $user->articles()->where(‘status’, 1)->select(); “`
4. 多重关联与别名
一个模型可定义多个关联,如用户有收货地址、订单等。
class User extends Model { public function orders() { return $this->hasMany(Order::class, 'user_id', 'id'); } public function profile() { return $this->hasOne(UserProfile::class, 'user_id', 'id'); } }
同时预载入多个关联:
“`php User::with([‘orders’, ‘profile’])->select(); “`
基本上就这些。只要模型中定义好关联方法,ThinkPHP 会自动处理 SQL 联查,让代码更清晰简洁。注意合理使用
with
减少数据库查询次数。