laravel提供了几种便捷的关联查询方法,如果我们可以灵活运用这几种方法,可以大大的提供sql查询效率与开发时间。为我们深入理解laravel机制,及php的新特性有很大的帮助.
前言
建议在学习测试过程中安装 Laravel Debugbar 参考网址 :
https://blog.891125.com/php/how-to-use-laravel-debugbar.html 如何使用Laravel Debugbar?
https://github.com/barryvdh/laravel-debugbar Debugbar git地址
一、hasOne 一对一查询
1.1 用到的表
1.1.1 category 分类表 id name pid
1.1.2 app 应用表 id name category_id sub_category_id
1.2 app 模型写hasOneCategory hasOneSubCategory 两个方法
<?php namespace App; use Illuminate\Database\Eloquent\Model; class App extends Model { protected $table = 'app'; protected $fillable = ['name','category_id','sub_category_id']; public function hasOneCategory(){ return $this->hasOne(Category::class,'id','category_id');//第二个参数是category的id 第三个参数是app的category_id } public function hasOneSubCategory(){ return $this->hasOne(Category::class,'id','sub_category_id'); }
1.3 定义一个TestController
//with 方法使用了两个hasOne 分别是‘分类’和‘子分类' 下面还会提到更详细的用法 $data = App::with('hasOneCategory','hasOneSubCategory')->where('id','<','123611')->where('id','>','123601')->get(); //dd($data) // 可以查看一下数据的结构 echo 1;//不输出任何东西貌似使用不了DebugBar 工具 return view('welcome');
1.3.1 产生如下sql
1.3.2 可以看到只用了三次查询就查到了对应的分类 如果不用hasOne 方法,使用传统的left join 方法则会产生N+1此查询,因此hasOne可以大大的提高sql的效率。
二、hasMany 一对多方式查询
2.1 用到的表
2.1.1 tags 标签表 id name img
2.1.2 app_tags 应用标签表 tags_id app_id
2.2 在 app model 中增加 hasManyTags 方法
public function hasManyTags(){ return $this->hasMany('App\AppTags','app_id','id'); }
2.3 在TestController 中写入
$data = App::with('hasManyTags')->where('id','<','123611')->where('id','>','123601')->get();
2.4 可以查询到单个应用所有标签id
三、belongsTo 一对一查询
3.1 需要的表
3.1.1 user 表 id name
3.2.2 phone 表 id user_id number
3.2 phone model 中写入
public function belongsToUser(){ return $this->belongsTo(User::class,'user_id','id') }
3.2 在TestController 中写入
$data = AppTags::with('belongsToUser')->where('number',110)->first(); echo 1;
四、belongsToMany 多对多查询
4.1 需要的表
4.1.1 app 表
4.1.2 app_tags 表
4.1.3 tags 表
4.2 在tags 表中定义 belongsToManyApp
public function belongsToManyApp(){ return $this->belongsToMany(App::class,'App_tags','tags_id','app_id'); }
4.3 在TestController 写入
$data = Tags::where('file_name','fanying')->with(['belongsToManyApp'=>function($query){ $arr = ['id','name','img','size','unit','intro','score','version','created_at','published_at','updated_at','hits','category_id','sub_category_id']; return $query->select($arr)->take(10)->skip(0)->with(['hasOneCategory'=>function($query){ return $query->select('file_name','name'); },'hasOneSubCategory'])->where('published_at','<=',Carbon::now())->orderBy('id','desc'); }])->first(); echo 1;
4.4 可以看到如下sql
4.5 需要解释一下4.3 的with语法
4.5.1 with 可以接受数组形式的参数,数组形式的还可以写匿名函数 然后匿名函数里写对应的条件。
4.5.2 with 还支持 "." 分法 举个例子
//App model public function belongsToManyTags(){ return $this->belongsToMany(Tags::class,'app_tags','app_id','tags_id')->withPivot('app_id','tags_id');//withPivot指定了中间件需要的字段 } //TestController $data = App::where('id',8640)->with('belongsToManyTags.belongsToManyApp')->first();
上面这句话上面意思呢,指的就是 "取出id为8640应用的详情,然后取出他所有的标签,然后取出这个标签所关联的所有app" 类似于下面的写法
$data = App::where('id',8640)->with(['belongsToManyTags'=>function($query){ return $query->with(['belongsToManyApp'=>function($query){ return $query->take(10); }]); }])->first();
参考链接 http://laravel-china.org/docs/5.1/eloquent-relationships
结束语
本文有任何错误,或有任何疑问,欢迎留言说明。
网友最新评论