zoukankan      html  css  js  c++  java
  • Laravel之Eloquent ORM关联

    一.一对一
    
    1.主对从(hasOne)
    从User模型中取出用户的手机
    
    User模型中:
    
    /**
    * 获取关联到用户的手机
    */
    public function phone()
    {
    	return $this->hasOne('AppPhone');
    	// return $this->hasOne(Phone::class);
    }
    
    phone默认有个user_id外键关联user模型的id,所以上面的应该是
    return $this->hasOne('AppPhone', 'id', 'user_id');//第二个参数是被关联模型的(User模型中的)字段,第三个参数是当前模型的需要和被关联模型对应的字段(此处Phone模型字段)
    
    调用:
    User::find(1)->phone; //作为属性调用
    User::find(1)->phone()->get();//作为方法调用
    
    或者:
    $user = User::find(1);
    $phone = $task->phone()->get();
    如果对phone的结果进一步过滤,可以加where
    $phone = $task->phone()->where('is_active', 1)->get();
    
    
    对应原生的SQL查询:
    select * from `lar_users` where `lar_users`.`id` = 1 limit 1;
    select * from `lar_phones` where `lar_phones`.`id` = 1 and `lar_phones`.`id` is not null limit 1;
    
    2.从对主(belongsTo)
    /**
    * 获取任务模型对应的用户
    */
    public function user()
    {
            return $this->belongsTo(User::class, 'user_id', 'id');//和前面的相反,第二个参数是当前模型的字段,第三个参数是关联模型的字段
    }
    
    对应原生SQL:
    select * from `lar_tasks` where `lar_tasks`.`id` = 1 limit 1;
    select * from `lar_users` where `lar_users`.`id` = 1 limit 1;
    
    两者原生的SQL语句有个区别是加了is not null;
    
    二.一对多
    
    1.一主对多从
    
    public function tasks()
    {
    	return $this->hasMany(Task::class, 'user_id', 'id');
    }
    
    原生sql
    select * from `lar_users` where `lar_users`.`id` = ? limit 1
    select * from `lar_tasks` where `lar_tasks`.`user_id` = ? and `lar_tasks`.`user_id` is not null
    
    2.多从对一主
    这跟一对一的从对主一样
    
    
    三.对关联关系进行查询(where子查询)
    比如需要查询有三条任务的用户,使用has,传入关联属性
    User::has('tasks', '>', 3)->get()
    
    对应的原生SQL语句:
    select * from `lar_users` where (select count(*) from `lar_tasks` where `lar_tasks`.`user_id` = `lar_users`.`id`) > 3;
    
    更复杂的可以使用whereHas和orWhereHas,查询有任务,且任务名称为'发送'开头的用户
    User::whereHas('tasks', function($query) {
    	$query->where('name', 'like', '发送%');
    	})->get();
    
    对应的原生SQL语句:
    select * from `lar_users` where (select count(*) from `lar_tasks` where `lar_tasks`.`user_id` = `lar_users`.`id` and `name` like ?) >= 1;
    
    四.渴求式加载
    关联关系数据时"懒惰式加载"的,也就是在第一次用到的时候才会被加载.
    
    1.懒惰加载产生的问题
    打印每个用户的任务名称
    $users = User::all();
    foreach ($users as $user) {
    	$user->tasks->name;
    }
    
    这将先查询一次users表,再挨个去查询tasks表,有多少个用户就查询多少次
    原生的SQL语句如下所示:
    select * from `lar_users
    select * from `lar_tasks` where `lar_tasks`.`user_id` = ? and `lar_tasks`.`user_id` is not null limit 1
    select * from `lar_tasks` where `lar_tasks`.`user_id` = ? and `lar_tasks`.`user_id` is not null limit 1
    select * from `lar_tasks` where `lar_tasks`.`user_id` = ? and `lar_tasks`.`user_id` is not null limit 1
    select * from `lar_tasks` where `lar_tasks`.`user_id` = ? and `lar_tasks`.`user_id` is not null limit 1
    .............
    
    2.使用渴求式加载:
    $users = User::with('tasks')->get();
    foreach ($users as $user) {
    	$user->tasks->name;
    }
    
    原生的SQL语句如下所示:
    select * from `lar_users
    select * from `lar_tasks` where `lar_tasks`.`user_id` in (?, ?)

    五.关联模型的insert/update 1.基本的insert $user = User::find(1); $user->tasks()->create(['name' => '测试任务1']); 也可以使用save/saveMany,不过save接受的是一个模型实例,create接受原生数组.user_id被自动带入到插入的数组中. 原生SQL语句: select * from `lar_users` where `lar_users`.`id` = ? limit 1 insert into `lar_tasks` (`name`, `user_id`, `updated_at`, `created_at`) values (?, ?, ?, ?); 2.常见的从对主的更新(belongsTo) 触发父模型的更新时间戳(update_at) class Task extends Model { protected $touches = ['user']; protected $fillable = ['name','user_id']; public function user() { return $this->belongsTo(User::class, 'user_id', 'id'); } } 更新: $task = Task::find(1); $task->name='最新测试'; $task->save();

    如果仅仅需要关联表的部分字段,则可以使用闭包,但字段中必须包含该关联表的主键,如
    $users = User::with(['tasks'=>function($query){
      return $query->select('id', 'task_name');
    }])->get();

     

  • 相关阅读:
    2013年工作中用到的10个命令:11-20
    2013年工作中用到的10个命令:11-20
    2013年工作中用到的10个命令:1-10
    OpenJDK源码研究笔记(十):枚举的高级用法,枚举实现接口,竟是别有洞天
    OpenJDK源码研究笔记(十):枚举的高级用法,枚举实现接口,竟是别有洞天
    Java实现 LeetCode 240 搜索二维矩阵 II(二)
    Java实现 LeetCode 239 滑动窗口最大值
    Java实现 LeetCode 239 滑动窗口最大值
    Java实现 LeetCode 239 滑动窗口最大值
    Java实现 LeetCode 238 除自身以外数组的乘积
  • 原文地址:https://www.cnblogs.com/itfenqing/p/6930432.html
Copyright © 2011-2022 走看看