Laravel 模型关联建立与查询

Posted 青及笄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel 模型关联建立与查询相关的知识,希望对你有一定的参考价值。

Laravel 关联查询总结

一. Laravel 对象关联关系

1. 对象与数据库表的关联

Laravel有一个强大的数据库工具ORM Eloquent,是每张数据表对应一个Model,对Model的操作就对应数据库的操作,你只用管对model的操作,SQL语句则根据对象模型操作自动生成。
之前写过一篇相关基础介绍的文章:链接: Laravel model 模型用法和部分问题解方法

2. 对象(表)之间的关联关系

在我们代码编写过程中,对象之间有着多种的关联关系;

  1. 一对一 例如:学生有唯一对应的班级
  2. 一对多 例如:班级有很多个学生
    相应的在我们的表中对应的表现就是外键,通过外键与主键相等的方式,进行关系的建立,那么在Laravel中如何进行关联查询呢?

二. 对象关系映射关联关系的建立

1. Model配置关联关系

我们想要在后续的查询中方便进行关联查询,首先我们要在Model中配置相关的关联关系:

//name是关联关系的名称,通常我们使用表名代替,方便记忆
    public function name()
    
    	//返回我们的关系,使用不同的方法进行关系建立
        return $this->belongsTo('关联对象', '关联外键', '关联主键');
    

2. 关联关系种类方法

我们这里以班级class,负责人principal,学生student作为参考。

hasOne

班级有一个负责人,那就在班级对象中,新增负责人关联

    public function Principal(): \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo
    
    	//hasOne( related:关联的对象模型 , foreignKey:'关联字段名')
        return $this->hasOne(Principal::class, 'class_id');
    

hasMany

一个班级有很多个学生,也就是一对多的关系,新增关联

    public function student(): \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo
    
    	//hasOne( related:关联的对象模型 , foreignKey:'关联字段名')
        return $this->hasMany(Student::class, 'class_id');
    

belongsTo

负责人负责一个班级,那就在负责人对象中,可以新增班级关联

    public function class(): \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo
    
    	//belongsTo( related:关联的对象模型 , foreignKey:'关联字段名')->->withDefault();
        return $this->belongsTo(Class::class, 'principal_id')->withDefault();
    

withDefault
正常情况下 负责人对应的班级是存在的,如果班级表中的数据删除,那么关联模型就会返回一个null值,避免所属父级被删除导致的异常问题

就是为了解决返回null所带来问题的。

belongsToMany

但是假设学生可以报多个班级,那么学生和班级的关系就会变成多对多的关系,我们通常会使用一个中间的关系表,进行关联

public function class()
    
        return $this->belongsToMany('目标对象','中间表','本表在中间表外键','目标表在中间表中外键','第三个参数如果对应的不是本表的主键则需要填写,反之不需要');
    

hasOneThrough

远程关联一对一,比方说一个用户拥有一个账本,账本中存在很多条消费记录,我想从消费记录中获取到该用户的信息,就需要远程一对一

public function record()
    
        return $this->hasOneThrough('目标对象','中间表','本表在中间表外键','目标表在中间表中外键','第三个参数如果对应的不是本表的主键则需要填写,反之不需要');
    

hasManyThrough

public function record()
    
        return $this->hasManyThrough('目标对象名称','中间表','本表在中间表外键','目标表在中间表中外键','当前表与中间表关联字段名称','中间表和目标表关联的字段名称');
    

三. 对象关系映射关联关系的几种方法

1. with

介绍

with 是一种渴求式预加载,with 更像 sql 中的 join,无论关联的结果中有没有值都会返回,如果没有就会返回一个空

使用方法

//with 中第一个参数就是我们上面建立关系的方法名
$query = Model::with('关系名称')->get();

我们如果想要在进行关联查询时,对其进行筛选,我们也可以在with中写方法:

//查询所有的用户,查询条件:发布过标题中有first的post 
$query = Model::with([
'关系名称' => function ($query) 

//对关联表进行筛选,可以用where,orWhere 等
  	$query->where('title', 'like', '%first%');

])->get();

如果我们想要携带参数:

//查询所有的用户,查询条件:发布过标题中有first的post 
$query = Model::with([
'关系名称' => function ($query) use ($searchWord) 

//对关联表进行筛选,可以用where,orWhere 等
  	$query ->where('title', 'like', '%'.$searchWord.'%');

])->get();

2. whereHas

介绍

whereHas只会返回有结果的值,就可以有效避免with中出现空的返回值的情况

使用方法

基础用法与with相似

$query = Model::whereHas('关系名称', function ($query) 
  $query->where('title', 'like', '%first%');
)->get();

但是whereHas可以嵌套

$query = TeacherModel::query()->whereHas(
                'merchant' , function ($query)
                     $query->whereHas(
                            'groups',function($query)
                            $query->where("查询字段","目标值");
                            
                        );
                
        )->where('name','like','%'.$searchWord.'%')->get(['id','name']);

四. 写在最后

laravel 中的模型关系是我们在进行多表联查时十分重要的一部分,目前基本的使用可以达到效果,但是感觉并不能十分透彻的理解,等后续在使用的过程中,有了自己的理解再来补充

二十八PHP框架Laravel学习笔记——模型的关联查询

二.关联查询

  1. 前几篇博文,了解了三种基础的关联模型,并简单的进行查询;
  2. 本节课,我们详细的了解更多的查询方案;
    //下面两种查询是一样的;
$books = User::find(19)->book; 
$books = User::find(19)->book()->get(); 

在这里插入图片描述

//可以采用 where 筛选或闭包

$books = User::find(19)->book() ->where('id', 1)->orWhere('id', 11)->get(); 


在这里插入图片描述

$books = User::find(10)->book()->where(function ($query) { 
	$query->where('id', 1)->orWhere('id', 11); 
})->get(); 

在这里插入图片描述

  1. 使用 has()方法,可以查询某些条件下的关联查询数据;
    //获取存在关联书籍的用户列表(言下之意:至少一本书)
$users = User::has('book')->get(); 
return $users; 

在这里插入图片描述

//获取存在关联书籍(并超过 3 条)的用户列表
$users = User::has(‘book’,’>=’, 3)->get();
return $users;
在这里插入图片描述

  1. 使用 whereHas()方法,创建闭包查询;
    //whereHas 闭包用法
$users = User::whereHas('book', function ($query) { 
	//这里$query 是 book 表,通过 user_id 查询,返回 user 表数据 
	$query->where('user_id', 19); })->get(); 
return $users; 

在这里插入图片描述

  1. 使用 doesntHave()方法,即 has()的反向操作;
    //获取不存在关联书籍的用户列表,闭包用法:whereDoesntHave()
$users = User::doesntHave('book')->get(); 
return $users;

在这里插入图片描述

  1. 使用 withCount()方法,可以进行关联统计;
    //关联统计,会自动给一个 book_count 字段
    //统计每个用户有多少本书
$users = User::withCount('book')->get(); 
return $users; 

在这里插入图片描述

//给多个关系添加统计:profile_count,book_count

$users = User::withCount(['profile', 'book'])->get(); 
return $users; 

在这里插入图片描述

//关联统计再结合闭包进行筛选,还可以设置别名

$users = User::withCount(['profile', 'book' => function ($query) { 
	//这里限制被统计的记录 
	$query->where('user_id', 19); }])->get(); 
	return $users;

在这里插入图片描述
在这里插入图片描述

以上是关于Laravel 模型关联建立与查询的主要内容,如果未能解决你的问题,请参考以下文章

laravel中关联模型查询选择性的字段

laravel 中with关联查询限定查询字段

在 Laravel 4 中查询数据透视表

laravel如何查特定中间表数据的关联数据

二十八PHP框架Laravel学习笔记——模型的关联查询

laravel ORM 模型关联 with () 用法