laravel - Eloquent ORM(关联关系)

什么是表关联关系
一个数据库中表和表之间必然会存在一些联系,关联关系就是这个意思。

而通过Eloquent我们可以方便的处理这些关系。

定义关联关系
一对一

比如说一个用户(User)会有一个手机(Phone),这种一对一的关系我们直接在User中定义一个phone方法就是可以了。

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model{
    /**
     * 获取关联到用户的手机
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
        //在这个例子中Phone模型默认有一个user_id外键,
        //如果你希望重写这种约定,可以传递第二个参数到hasOne方法。
        return $this->hasOne('App\Phone', 'foreign_key');
        /*Eloquent 假设外键应该在父级上有一个与之匹配的id,换句话说,Eloquent 将会通过user表的id值去phone表中查询user_id与之匹配的Phone记录。如果你想要关联关系使用其他值而不是id,可以传递第三个参数到hasOne来指定自定义的主键:*/
        return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
        //说白了就是hasOne('关联Eloquent', '被关联表的key', '本表key')
    }
}

使用时

//获取phone实例化
$phone = User::find(1)->phone;

相对应关联
user现在可以找到phone,那么我们怎么通过phone找到user
以此类推实例

namespace App;

use Illuminate\Database\Eloquent\Model;

class Phone extends Model{
    /**
     * 获取手机对应的用户
     */
    public function user()
    {
        /*Eloquent 将会尝试通过Phone模型的user_id去User模型查找与之匹配的记录。Eloquent 通过关联关系方法名并在方法名后加_id后缀来生成默认的外键名。*/
        return $this->belongsTo('App\User');
        //参数类似上面的一对一
    }
}

一对多
一个文章可以有多条点评
通过文章查找点评 demo

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model{
    /**
     * 获取文章的点评
     * return $this->hasManay('App\Comment(这里是要关联的模型,这个例子是评论模型Comment)', 'article_id'(这里是关联外键的字段名,这个例子就是 article_id 字段), 'id'(对应关联模型的主键,这里的 id 是关联 article 表的id));

}
     */
    public function comments()
    {
        //类似hasOne存在如下参数
        return $this->hasMany('App\Comment', 'article_id', 'id ');
    }
}

一对多(逆向)
通过点评访问文章。belongsTo

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model{
    /**
     * 获取点评对应的文章
     */
    public function post()
    {
        return $this->belongsTo('App\Post', 'id', 'article_id');
    }
}

多对多

一个用户有多个角色,同时一个角色被多个用户共用。例如,很多用户可能都有一个“Admin”角色。要定义这样的关联关系,需要三个数据表:users、roles和role_user,role_us
er表按照关联模型名的字母顺序命名,并且包含user_id和role_id两个列。
belongsToMany

就是两个表的数据是多对多的关系。
a表的一个数据在b表可以查到多条数据,b表的数据也可以在a表查到多条数据。
当然两个表的关系是通过一个中间表来组织起来的。
中间表的默认命名方式为:a_b,可以修改
多对多的逆向关联和正向是一样的。

用上面的例子:

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model{
    /**
     * 用户角色
     */
    public function roles()
    {
        //可以看到第一个是关联的表,中间表,键,键
        return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
    }
}

对于Role也一样

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model{
    /**
     * 角色用户
     */
    public function users()
    {
        return $this->belongsToMany('App\User');
    }
}

关于中间表

上面提到了中间表,这里进行一下扩展:

访问中间表的数据,可以使用pivot属性,他会获得一个中间表的实例。

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

foreach ($user->roles as $role) {
    echo $role->pivot->created_at;
}

当然,在默认情况下通过pivot我们只能访问关联键也就是上例的user_id和role_id。
要想访问其他列,例如上面的created_at需要在关联的时候定义。
使如下方法定义:

//获得column1,column2
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
//获得created_at和updated_at
return $this->belongsToMany('App\Role')->withTimestamps();

关联的时候可以使用wherePivot和wherePivotIn方法过滤结果集。

//要求中间表记录符合approved=1。
return $this->belongsToMany('App\Role')->wherePivot('approved', 1);
//要求中间表记录符合priority在1,2之中。
return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);

你可能感兴趣的:(laravel - Eloquent ORM(关联关系))