Code前端首页关于Code前端联系我们

Laravel开发学习笔记:模型关联问题

terry 2年前 (2023-09-25) 阅读数 57 #后端开发

关联概念

关联模型,即两个或多个表绑定在一起,并按照一定的规则关联起来。

示例:

  • 学生(学生表)与个人信息卡(信息表)匹配,这是一对一的;
  • 一篇博文(帖子表)对应多条评论(评论表),这是一对多的关系;
  • 一个用户(用户表)对应多个职位(权限表),一个职位可以有多个用户;那么,这是一个多对多的关系;

当然,还有更复杂的关系,都是基于此。

本文仅讨论这三种基本关系。

因为是关联,所以必然有绑定的概念。当有数据库操作时,关联表也会发生变化;这意味着关联模型。

一对一关联

1。我们以下面两张表为例进行演示:用户左边

Laravel开发学习笔记: 模型的关联查询

主表、♻‾键。在 Laravel 中,默认主键是 id。

个人资料的右侧是时间表,主键是id,是用户的。在 Laravel 中,外键模式格式为 primary_tablename_primarykey

然后使用命令创建对应两个表的model模型:

php artisan make:model Models/User
php artisan make:model Models/Profile

然后为两个表进行注释

: : 在主表中,写入相关附表的代码、格式及参数说明,如下:

publicfunctionprofile(){return$this->hasOne(Profile::class,'user_id','id');}

然后即可在控制类中使用:♷O结果:

{"id":1,"user_id":19,"hobby":"喜欢大姐姐","status":1}

这个过程中,执行了两条SQL语句,分别是:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select*from`laravel_profiles`where`laravel_profiles`.`user_id`=19and`laravel_profiles`.`user_id`isnotnulllimit1

3、反向关联:在附表中,将代码写为 。 ,格式及参数如下:

publicfunctionuser(){return$this->belongsTo(User::class,'user_id','id');}

那么可以在控制类中使用:

$users= Profile::find(1)->user;return$users;

输出结果:

{"id":19,"username":"蜡笔小新","password":"123","gender":"男",......}

此过程中,执行的SQL语句为:

select*from`laravel_profiles`where`laravel_profiles`.`id`=1limit1select*from`laravel_users`where`laravel_users`.`id`=19limit1

1-to-0.3 多个关联

1. 我们用下面两张表来演示:

Laravel开发学习笔记: 模型的关联查询

可以看出,这是一个一对多的关联

类似地,为图书表创建模型:

php artisan make:model Models/Book

并进行注释:

php artisan ide-helper:models

2、前向关联:在‶、在主表中在代码、格式和参数解释如下:

publicfunctionbook(){return$this->hasMany(Book::class,'user_id','id');}

那么,可以在控制类中使用:

$books= User::find(19)->book;return$books;

执行结果:

[{"id":1,"user_id":19,"title":"《莎士比亚》"},{"id":10,"user_id":19,"title":"《热情天堂》"},{"id":11,"user_id":19,"title":"《完美人生》"},{"id":29,"user_id":19,"title":"《哈利波特》"}]

这个过程中,执行了两条SQL语句:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select*from`laravel_books`where`laravel_books`.`user_id`=19and`laravel_books`.`user_id`isnotnull

3 ,一对一获取数据很多关联,如果想再次过滤,可以使用如下方法:

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

执行结果为:

[{"id":11,"user_id":19,"title":"《完美人生》"}]

执行的SQL为:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select*from`laravel_books`where`laravel_books`.`user_id`=19and`laravel_books`.`user_id`isnotnulland`id`=11

4、反向关联:在附中表,编写与主表相关的代码。与一对一反向关联一致。

publicfunctionuser(){return$this->belongsTo(User::class,'user_id','id');}

然后执行控制类中的代码:

$users= Book::find(1)->user;return$users;

执行结果为:

{"id":19,"username":"蜡笔小新","password":"123","gender":"男",......}

执行的SQL为:

select*from`laravel_books`where`laravel_books`.`id`=1limit1select*from`laravel_users`where`laravel_users`.`id`=19limit1

10.4多对多关联
php artisan make:model Models/User
php artisan make:model Models/Profile

。多对多关联比前两种更复杂一些需要中间表,一共三张;

我们使用以下三张表进行演示:

Laravel开发学习笔记: 模型的关联查询

左表:.users:用户表

中表:.role_users:中间表,默认表 名称是这样的。然后两边关联的默认外键:user_id、role_id。

右表:.roles:权限表

对于这三个表,只需要对用户表和和进行建模。撰写评论:

php artisan ide-helper:models

2、高级关联:设置中为空 多对多

然后就可以在控制类中使用了。例如,多对多关联的输出:检查用户19是否有权限

$roles= User::find(19)->role;return$roles;

输出结果:

[{"id":2,"type":"评论审核专员","pivot":{"user_id":19,"role_id":2}},{"id":3,"type":"图片监察员","pivot":{"user_id":19,"role_id":3}},{"id":1,"type":"超级管理员","pivot":{"user_id":19,"role_id":1}}]

多对多会产生一个中间列:pivot,其中包含多对多双身份;

执行的SQL为:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select`laravel_roles`.*,`laravel_role_users`.`user_id`as`pivot_user_id`,`laravel_role_users`.`role_id`as`pivot_role_id`from`laravel_roles`innerjoin`laravel_role_users`on`laravel_roles`.`id`=`laravel_role_users`.`role_id`where`laravel_role_users`.`user_id`=19

3。获取权限列表中的具体数据与一对多的操作方法类似,但要注意返回的Table名称;

$roles= User::find(19)->role()->where('role_id',1)->get();return$roles;$roles= User::find(19)->role;return$roles->where('id',1);

执行结果:

[{"id":1,"type":"超级管理员","pivot":{"user_id":19,"role_id":1}}]

执行的SQL为:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select`laravel_roles`.*,`laravel_role_users`.`user_id`as`pivot_user_id`,`laravel_role_users`.`role_id`as`pivot_role_id`from`laravel_roles`innerjoin`laravel_role_users`on`laravel_roles`.`id`=`laravel_role_users`.`role_id`where`laravel_role_users`.`user_id`=19and`role_id`=1

4,反向关联:多对多方法与两种反向方法相同。在模型中

publicfunctionuser(){return$this->belongsToMany(User::class,'role_users','role_id','user_id');}

然后在控制类中执行:

$users= Role::find(1)->user;return$users;

执行结果如下,即查询具有1权限的用户(超级管理员)::execute 5。多对多会产生一个中间列:pivot,其中包含多对Many双ID

如果您希望数据透视表字段包含其他中间表字段,您可以自行添加或编辑字段名称。

例如在正向关联中,修改为:

publicfunctionrole(){return$this->belongsToMany(Role::class,'role_users','user_id','role_id')->withPivot('details','id')->as('pivot_name');}

,然后执行:

$roles= User::find(19)->role()->where('role_id',1)->get();return$roles;

执行结果为:

[{"id":1,"type":"超级管理员","pivot_name":{"user_id":19,"role_id":1,"details":"啦","id":8}}]

执行的SQL为:,可以在方法中绑定Filter数据;

例如前向相关中,改为:

publicfunctionrole(){return$this->belongsToMany(Role::class,'role_users','user_id','role_id')->wherePivot('id',1);}

还有wherePivotIn,以及四种派生方法。

然后执行:

$roles= User::find(19)->role;return$roles;

输出结果为:

[{"id":2,"type":"评论审核专员","pivot":{"user_id":19,"role_id":2}}]

执行的SQL为:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select`laravel_roles`.*,`laravel_role_users`.`user_id`as`pivot_user_id`,`laravel_role_users`.`role_id`as`pivot_role_id`from`laravel_roles`innerjoin`laravel_role_users`on`laravel_roles`.`id`=`laravel_role_users`.`role_id`where`laravel_role_users`.`user_id`=19and`laravel_role_users`.`id`=1

除了一对一、一对多、多对多之外,还有远程一对一- 一对一和远程一对多,以及多态一对一、多态一对多、多态多对多。

相关请求

上一篇文章介绍了三种常用的请求。本节介绍一些常用的查询方案。

1。下面两个题的方法是一样的:

$books= User::find(19)->book;$books= User::find(19)->book()->get();

2。过滤或关闭起作用的地方。

示例:

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

执行结果:

[{"id":1,"user_id":19,"title":"《莎士比亚》"},{"id":11,"user_id":19,"title":"《完美人生》"}]

执行的SQL为:

select*from`laravel_users`where`laravel_users`.`id`=19limit1select*from`laravel_books`where`laravel_books`.`user_id`=19and`laravel_books`.`user_id`isnotnulland`id`=1or`id`=11

3. 在某些情况下,使用has()方法来查询相关查询数据。例如:

$users= User::has('book')->get();return$users;$users= User::has('book','>=',3)->get();return$users;

执行的SQL为:

select*from`laravel_users`whereexists(select*from`laravel_books`where`laravel_users`.`id`=`laravel_books`.`user_id`)select*from`laravel_users`where(selectcount(*)from`laravel_books`where`laravel_users`.`id`=`laravel_books`.`user_id`)>=3

执行结果为:

[{"id":19,"username":"蜡笔小新","password":"123",......},{"id":20,"username":"路飞","password":"123",......},{"id":21,"username":"黑崎一护","password":"456",......},{"id":24,"username":"小明","password":"123",......},{"id":25,"username":"孙悟饭","password":"123",......},......][{"id":19,"username":"蜡笔小新","password":"123",......}]

4。使用whereHas()方法创建闭包查询;

$users= User::whereHas('book',function($query){$query->where('id',2);})->get();return$users;

执行的SQL为:

select*from`laravel_users`whereexists(select*from`laravel_books`where`laravel_users`.`id`=`laravel_books`.`user_id`and`id`=2)

5。使用 isntHave() 方法,它是 has() 的逆操作:

$users= User::doesntHave('book')->get();return$users;

执行的 SQL 为:

select*from`laravel_users`wherenotexists(select*from`laravel_books`where`laravel_users`.`id`=`laravel_books`.`user_id`)

6、使用 withCount() 方法进行相关性统计;

例如:

$users= User::withCount('book')->get();return$users;

执行的 SQL 为:

select`laravel_users`.*,(selectcount(*)from`laravel_books`where`laravel_users`.`id`=`laravel_books`.`user_id`)as`book_count`from`laravel_users`

又如:

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

执行的 SQL 为:

select`laravel_users`.*,(selectcount(*)from`laravel_profiles`where`laravel_users`.`id`=`laravel_profiles`.`user_id`)as`profile_count`,(selectcount(*)from`laravel_books`where`laravel_users`.`id`=`laravel_books`.`user_id`)as`book_count`from`laravel_users`

又​​如:

php artisan make:model Models/User
php artisan make:model Models/Profile

及以上。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门