Laravel中Eloquent ORM 关联关系的操作

关联数据

定义关联关系

一对一

class User extends Model{

// 获取关联到用户的手机

public function phone()

{

// Phone 模型默认有一个 user_id 外键

return $this->hasOne('App\Phone');

// 外键应该在父级上有一个与之匹配的id(或者自定义 $primaryKey)

// return $this->hasOne('App\Phone', 'foreign_key');

// 用User的local_key,匹配Phone的foreign_key

// return $this->hasOne('App\Phone', 'foreign_key', 'local_key');

}

}

$phone = User::find(1)->phone; // 获取用户的手机模型

相对的关联

class Phone extends Model {

// 获取手机对应的用户

public function user()

{

return $this->belongsTo('App\User');

// return $this->belongsTo('App\User', 'foreign_key');

// return $this->belongsTo('App\User', 'foreign_key', 'other_key');

}

}

$user = Phone::find(1)->user; // 查询phone的id=1对应的user

$user = Phone::where('number','188**')->first()->user; // 查询电话为188的用户

一对多

class User extends Model{

// 获取文章

public function article()

{

return $this->hasMany('App\Comment');

// return $this->hasMany('App\Comment', 'foreign_key');

// return $this->hasMany('App\Comment', 'foreign_key', 'local_key');

}

}

$articles = User::find(1)->article; // 返回 userid为1 的所有文章

$article = User::find(1)->article()->where('title', 'aa')->first(); // 返回某一篇

一对多(逆向)

class Article extends Model{

public function user()

{

return $this->belongsTo('App\User');

// return $this->belongsTo('App\Post', 'foreign_key');

// return $this->belongsTo('App\Post', 'foreign_key', 'other_key');

}

}

$user = Article::find($id)->user; // 返回文章的作者

多对多

需要三张数据表:users、roles 和 role_user,

role_user 表为关系表,默认按照关联模型名的字母顺序命名,并且包含 user_id 和 role_id 两个列。

class User extends Model{

/**

* 用户角色

*/

public function roles()

{

//默认去role_user查找关系

// return $this->belongsToMany('App\Role');

return $this->belongsToMany('App\Role',"role_users");

// 定义键值

// return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');

}

}

$roles = User::find(1)->roles;

// 返回 [{"id":1,"name":"SuperManager","pivot":{"user_id":1,"role_id":1}},{"id":2,"name":"Manager","pivot":{"user_id":1,"role_id":2}}]

$roles = User::find(1)->roles()->orderBy('name')->get(); // 条件约束

注意我们获取到的每一个 Role 模型都被自动赋上了 pivot 属性。该属性包含一个代表中间表的模型,并且可以像Eloquent 模型一样使用。

如果你的 pivot 表包含额外的属性,必须在定义关联关系时进行指定:

return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');

如果你想要你的 pivot 表自动包含created_at 和 updated_at 时间戳,在关联关系定义时使用 withTimestamps 方法:

return $this->belongsToMany('App\Role')->withTimestamps();

过中间表字段过滤关联关系

return $this->belongsToMany('App\Role')->wherePivot('approved', 1);

return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);

关联查询

存在的关联查询

// 获取所有至少有一条评论的文章...

$posts = App\Post::has('comments')->get();

你还可以指定操作符和数目来自定义查询:

// 获取所有至少有三条评论的文章...

$posts = Post::has('comments', '>=', 3)->get();

还可以使用”.“来构造嵌套 has 语句,例如,你要获取所有至少有一条评论及投票的文章:

// 获取所有至少有一条评论获得投票的文章...

$posts = Post::has('comments.votes')->get();

如果你需要更强大的功能,可以使用 whereHas 和 orWhereHas 方法将 where 条件放到 has 查询上,这些方法允许你添加自定义条件约束到关联关系条件约束,例如检查一条评论的内容:

// 获取所有至少有一条评论包含foo字样的文章

$posts = Post::whereHas('comments', function ($query) {

$query->where('content', 'like', 'foo%');

})->get();

无关联结果查询

// 获取所有没有评论的博客文章

$posts = App\Post::doesntHave('comments')->get();

// 检查评论内容:

$posts = Post::whereDoesntHave('comments', function ($query) {

$query->where('content', 'like', 'foo%');

})->get();

统计关联模型

如果你想要在不加载关联关系的情况下统计关联结果数目,可以使用 withCount 方法,该方法会放置一个 {relation}_count 字段到结果模型

$posts = App\Post::withCount('comments')->get();

foreach ($posts as $post) {

echo $post->comments_count;

}

// 添加约束条件到查询一样来添加多个关联关系的“计数”:

$posts = Post::withCount(['votes', 'comments' => function ($query) {

$query->where('content', 'like', 'foo%');

}])->get();

echo $posts[0]->votes_count;

echo $posts[0]->comments_count;

// 为关联关系计数结果设置别名,从而允许在一个关联关系上进行多维度计数:

$posts = Post::withCount([

'comments',

'comments AS pending_comments' => function ($query) {

$query->where('approved', false);

}

])->get();

echo $posts[0]->comments_count;

echo $posts[0]->pending_comments_count;

渴求式加载

当以属性方式访问数据库关联关系的时候,关联关系数据是“懒惰式加载”的,这意味着关联关系数据直到第一次访问的时候才被加载。

$books = App\Book::all();

foreach ($books as $book) {

echo $book->author->name;

}

// 该循环要执行26次查询:1次是获取书本身,剩下的25次查询是为每一本书获取其作者。

$books = App\Book::with('author')->get();

foreach ($books as $book) {

echo $book->author->name;

}

// 在该操作中,只执行两次查询即可:

// select * from books

// select * from authors where id in (1, 2, 3, 4, 5, ...)

渴求式加载多个关联关系

$books = App\Book::with('author', 'publisher')->get();

嵌套的渴求式加载

// 加载所有书的作者及所有作者的个人联系方式:

$books = App\Book::with('author.contacts')->get();

带条件约束的渴求式加载

// 加载 title 包含 first 的文章

$users = App\User::with(['posts' => function ($query) {

$query->where('title', 'like', '%first%');

}])->get();

// 加载按created_at倒序的的文章

$users = App\User::with(['posts' => function ($query) {

$query->orderBy('created_at', 'desc');

}])->get();

懒惰渴求式加载

$books = App\Book::all();

if ($someCondition) {

$books->load('author', 'publisher');

}

// 设置更多的查询条件到渴求式加载查询上,可以传递一个闭包到 load 方法:

$books->load(['author' => function ($query) {

$query->orderBy('published_date', 'asc');

}]);

插入 & 更新关联模型

save 方法

$comment = new App\Comment(['message' => 'A new comment.']);

$post = App\Post::find(1);

$post->comments()->save($comment);

// save 方法会自动添加 post_id 值到新的Comment 模型。

保存多个关联模型,可以使用 saveMany 方法:

$post = App\Post::find(1);

$post->comments()->saveMany([

new App\Comment(['message' => 'A new comment.']),

new App\Comment(['message' => 'Another comment.']),

]);

create方法

该方法接收属性数组、创建模型、然后插入数据库。save 和 create 的不同之处在于 save 接收整个 Eloquent 模型实例而 create 接收原生 PHP 数组:

使用 create 方法之前确保先浏览属性批量赋值文档。

$post = App\Post::find(1);

$comment = $post->comments()->create([

'message' => 'A new comment.',

]);

从属关联关系

更新 belongsTo 关联, 使用associate 方法,该方法会在子模型设置外键:

$account = App\Account::find(10);

$user->account()->associate($account);

$user->save();

移除 belongsTo 关联的时候,使用dissociate 方法。该方法会设置关联关系的外键为 null:

$user->account()->dissociate();

$user->save();

多对多关联 的 附加/分离

假定一个用户可能有多个角色,同时一个角色属于多个用户,要通过在连接模型的中间表中插入记录附加角色到用户上,可以使用 attach 方法:

$user = App\User::find(1);

$user->roles()->attach($roleId);

// 以数组形式传递额外被插入数据到中间表:

$user->roles()->attach($roleId, ['expires' => $expires]);

移除一个多对多关联记录,使用 detach 方法。detach 方法将会从中间表中移除相应的记录;

但是,两个模型在数据库中都保持不变:

// 从指定用户中移除角色...

$user->roles()->detach($roleId);

// 从指定用户移除所有角色...

$user->roles()->detach();

接收数组形式的 ID 作为输入:

$user = App\User::find(1);

$user->roles()->detach([1, 2, 3]);

$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);

同步关联

sync 方法接收数组形式的 ID 并将其放置到中间表

// 任何不在该数组中的 ID 对应记录将会从中间表中移除

$user->roles()->sync([1, 2, 3]);

// 还可以和 ID 一起传递额外的中间表值:

$user->roles()->sync([1 => ['expires' => true], 2, 3]);

// 如果不想要脱离存在的ID,可以使用syncWithoutDetaching 方法:

$user->roles()->syncWithoutDetaching([1, 2, 3]);

切换关联

// 如果当前没有附加,则附加:如果给定ID当前被附加,则取消附加

$user->roles()->toggle([1, 2, 3]);

在中间表上保存额外数据

// 接收额外中间表属性数组作为第二个参数:

App\User::find(1)->roles()->save($role, ['expires' => $expires]);

更新中间表记录 updateExistingPivot

// 更新中间表中已存在的行,接收中间记录外键和属性数组进行更新

$user = App\User::find(1);

$user->roles()->updateExistingPivot($roleId, $attributes);

触发父级时间戳

当一个模型属于另外一个时,子模型更新时父模型的时间戳也被更新将很有用

例如,当 Comment 模型被更新时,你可能想要”触发“更新其所属模型 Post 的updated_at 时间戳。Eloquent 使得这项操作变得简单,只需要添加包含关联关系名称的 touches 属性到子模型即可:

class Comment extends Model{

// 触发的所有关联关系

protected $touches = ['post'];

// 关联关系

public function post()

{

return $this->belongsTo('App\Post');

}

}

更新 Comment 时,所属模型 Post 将也会更新其 updated_at 值

$comment = App\Comment::find(1);

$comment->text = 'Edit to this comment!';

$comment->save();

php orm中关联查询,【整理】Laravel中Eloquent ORM 关联关系的操作相关推荐

  1. oracle关联分组查询,oracle中关联查询、分组查询

    高级查询 1.关联查询 作用:可以跨越多表查询 --查询出员工的名字和他所在部门的的名字 //古老的写法 select first_name,name from s_emp,s_dept where ...

  2. sql中模糊查询的字段中包含百分号%的语句

    sql中模糊查询的字段中包含百分号%的语句: select * from 表名 where 字段 like '%\%%' ESCAPE '\'; Mysql里用\%,比如: select * from ...

  3. PHP利用分组查询groupby,Laravel 实现Eloquent模型分组查询并返回每个分组的数量 groupBy...

    Laravel 5.5 Linux mint 18 PHPStorm 最近刚玩Laravel,手册源码还没来得及看完就跃跃欲试做了个小项目,其中有个需求是分组查询数据库中的一个字段并返回每个分组中的数 ...

  4. mySQL主表与子表一对多关系,left join关联查询子表中其中一条记录

    1.left join测试示例 SELECTa.id,a.create_name,a.create_time,b.id AS bId,b.charge_key,b.check_status FROMp ...

  5. 在Eclipse中关联Android Private Libraries中文件的源代码

    相信有很多同学都遇到这样的问题,在Android项目中导入了第三方的库文件.虽然本地有源码,但是在Eclipse中却无法关联查看,提示信息显示Android Private Libraries不允许关 ...

  6. @many一对多---------解决一向多中主查询的数据库中没有的字段传递给子函数的问题

    @many一对多---------解决一向多(主查询传递给子查询参数为两个) 方法运用场景 主函数传递参数给子查询进行条件查找 方法简述 将变量参数转化为动态列,通过常用列传值方法传入 主查询 @Ma ...

  7. Laravel之Eloquent ORM

    一.ORM编程思想 1.1 Active Record 设计模式 Active Record 是一种数据访问设计模式,它可以帮助你实现数据对象Object到关系数据库的映射.应用Active Reco ...

  8. Laravel 的 Eloquent ORM学习

    创建模型 首先,创建一个 Eloquent 模型,生成的模型通常放在 app 目录中,但你可以通过 composer.json 随意地将它们放在可被自动加载的地方.所有的 Eloquent 模型都继承 ...

  9. Laravel之Eloquent ORM访问器调整器及属性转换

    一.查询构建器的get方法 查询构建器的get方法返回了一个集合$users = App\User::where('active', 1)->get(); foreach ($users as ...

  10. 在Laravel中使用数据库事务以及捕获事务失败后的异常

    Description 在Laravel中要想在数据库事务中运行一组操作,则可以在 DB facade 中使用 transaction 方法.如果在事务的闭包内抛出异常,事务将会被自动还原.如果闭包运 ...

最新文章

  1. c语言程序设计日历推后几天是星期几,C语言程序设计: 输入年月日 然后输出是星期几...
  2. 国内首个深度学习工程师认证标准发布
  3. 最近一段时间开发客户端app的感悟
  4. 中粮国际对话国际农民丰收节贸易会 谋定国际农贸现代化
  5. JDK 8 新特性 之 default关键字
  6. Linux shell中的那些小把戏
  7. 源码追踪,解决Could not locate executable null\bin\winutils.exe in the Hadoop binaries.问题
  8. oppor9splus科学计算机,oppo r9s plus手机驱动
  9. 制作OpenStack xpsp3镜像
  10. 创建Visual Studio离线升级包
  11. 光缆定位仪光衰点定位光纤识别方法
  12. 面试算法 香槟塔 ,算法:暴力算法
  13. android中倒计时动画,简单实现Android倒计时效果
  14. TZT3822EN静态信号测试分析系统
  15. 数组的归一化c语言,如何归一化频率数组
  16. c51语言的printf,KeilC51中的库函数printf
  17. 2022年最新整理,动力节点Java自学全套资源
  18. ZEGO教程:如何从零搭建小程序直播平台
  19. 我的找工作心酸奇葩史
  20. Qt-OpenCV学习笔记--计算周长--arcLength()

热门文章

  1. 国庆在家写了个简易版的在线简历网站
  2. ‘lengths‘ argument should be a 1D CPU int64 tensor, but got 1D cuda:0 Long tensor
  3. drools 6.5 决策表使用
  4. 修改《植物大战僵尸》的游戏存档
  5. 作为程序员,应该更关注代码质量还是只需要完成功能就好了?
  6. npm ERR! This is probably not a problem with npm. There is likely additional log ging output above.
  7. oppo r11 r11t解BL锁安装面具magisk详细教程
  8. Apache Flink如何处理背压
  9. java怎么查看源代码
  10. Python(关于运算符的运用的作业题)