场景:文章、评论和评论用户,一个文章有多个评论,每个评论有对应的用户,要求展示文章列表
文章模型
class Article extends Models{
/**
* @var string table name
*/
protected $table = 'article';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $primaryKey = 'article_id';
}
评论模型
class Comment extends Models{
/**
* @var string table name
*/
protected $table = 'comment';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $primaryKey = 'comment_id';
}
用户模型
class User extends Models{
/**
* @var string table name
*/
protected $table = 'user';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $primaryKey = 'user_id';
}
方案一:
一对多+一对一,最终执行一次article列表,一次comment whereIn, 一次user whereIn
Article模型增加:
/**
* 关联(一对多)
* @return HasMany
*/
public function comment()
{
return $this->hasMany(Comment::class, 'article_id', 'article_id');
}
Comment模型增加:
/**
* 关联(一对一)
* @return hasOne
*/
public function user()
{
return $this->hasOne(User::class, 'user_id', 'user_id');
}
$articleList = Article::query()
->with('comment','comment.user')
->get()
->toArray();
方案二:一对多模型里直接连表,最终执行一次article列表,一次whereIn+join
Article模型增加:
/**
* 关联(一对多)
* @return HasMany
*/
public function comment()
{
return $this->hasMany(Comment::class, 'article_id', 'article_id')
->leftJoin('user', 'comment.user_id', '=', 'user.user_id');
}
$articleList = Article::query()
->with('comment')
->get()
->toArray();
方案三:和方案二一样,只不过连表没有写在一对多关系里面
Article模型增加:
/**
* 关联(一对多)
* @return HasMany
*/
public function comment()
{
return $this->hasMany(Comment::class, 'article_id', 'article_id');
}
$articleList = Article::query()
->with(['comment'=>function($query){
$query->leftJoin('user', 'comment.user_id', '=', 'user.user_id');
}])
->get()
->toArray();
延伸:
// 展示存在评论和用户的文章
$articleList = Article::query()
->has('comment.user')//点语法 嵌套has
->with('comment','comment.user')
->get()
->toArray();
// 展示存在评论的文章
$articleList = Article::query()
->has('comment')
->with('comment','comment.user')
->get()
->toArray();
// 展示不存在评论的文章
$articleList = Article::query()
->doesntHave('comment')
->with('comment','comment.user')
->get()
->toArray();
// 获取评论大于3条的文章
$articleList = Article::query()
->has('comment','>',3)
->with('comment','comment.user')
->get()
->toArray();
// 获取至少带有十条评论内容包含 foo% 关键词的文章...
$posts = Article::query()
->whereHas('comment', function ($query) {
$query->where('content', 'like', 'foo%');
}, '>=', 10)
->get();