假设现在有3张表,分别是 articles 文章表,category 分类表,还要一个是 users 用户表。 关联度最深的还数 articles,因为它要存储该文章的分类,还有发布者。字段如下:
id title body categories_id user_id
为了说明问题,我们精简了表结构。接着是 分类表 category 的字段:
id category_name
最后是发布者 users 表字段:
id user_name user_type
好了准备工作做完了。假设要查询一篇文章,且需要连带查询出该文章的分类信息,发布者信息,最直观的是使用 join 关联查询。 类似下面的代码方式:
$articles =DB::table('articles')->join('categories', 'articles.id', '=', 'categories.id') ->join('users', 'users.id', '=', 'articles.user_id') ->select('articles.id','articles.title','articles.body','users.username', 'category.name') ->get();
但是这样写组装的SQL语句太复杂了。而且一点也不laravel。所以我们尝试着使用laravel eloquent orm 方式实现。
首先是创建表对应的模型 User.php,
<?php
namespace App\Model;
use Lib\Database\Model;
use App\Model\User;
use App\Model\Category;
class Article extends Model{
protected $table = 'articles';
public function user() { return $this->belongsTo(User::class, 'user_id', 'id'); }
public function category() { return $this->belongsTo(Category::class, 'category_id', 'id');}
}
再接着是 User 用户模型:
<?php namespace App\Model;
use Lib\Database\Model;
use App\Model\Article;
class User extends Model{
protected $table = 'users';
public function articles() { return $this->hasMany(Article::class, 'user_id', 'id'); }
}
最后是分类 Category 模型:
<?php
namespace App\Model;
use Lib\Database\Model;
use App\Model\Article;
class Category extends Model{
protected $table = 'category';
public function articles() { return $this->hasMany(Article::class, 'category_id', 'id'); }
}
经过上述3个模型的关联关系铺垫,现在查询一篇文章 articles, 同时关联上 users,category 表,就可以使用下面的写法:
$article = \App\Model\Article::with(['user','category'])->first();
上述语句在组装SQL的时候,先查询articles表的内容,然后分别使用 articels 查询结果的 id 列表用作筛选条件, 查询出 user 表,category 表,有三次SQL查询。
其实我们可以精准控制SQL执行的时机,比如只有在我们需要使用 user 信息的时候, 就可以这样使用:
$article = \App\Model\Article::first();
$user_name = $article->user->user_name;
上述方法,只有在调用 Article 模型的关联模型时,才会触发查询。效率要高一些。 同样的方法也适用于 Category 模型:
$category_name = $article->category->category_name;
写在最后
本文通过三张表的关联查询,使用laravel提供的模型关联方式,优雅而且可重用地实现了需求。 这远比使用原生查询来的效率高,可操作性也更强。
网友评论