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
![1468916071595227.png W_5VNDNH6540B9]OZH)99HN.png](/uploads/archive/201607/1468916071595227.png)
    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
结束语
本文有任何错误,或有任何疑问,欢迎留言说明。
网友最新评论