您的位置 首页 php

3分钟短文:Laravel模型一对一一对多关系真的乱吗?

引言

laravel模型不但提供了可供数据库操作的增删改查,还附加了很多功能,最关键的要数模型的关联关系。 本文说一说简单的一对一,和一对多关系。用代码说话,让大家更直观地理解。

代码时间

例如一个通讯录条目,一条通讯录,有一个手机号码,这是个一对一的关系。 在Contact模型文件内创建关联方法:

 class Contact extends Model
{
    public function phoneNumber()
    {
        return $this->hasOne(PhoneNumber::class);
    }
}  

上面这个写法,默认是有一个模型 PhoneNumber 所对应的表,且表内有一个字段名 contacts_id 作为外键。 如果这个外键不是 contacts_id ,那就手动指定:

 return $this->hasOne(PhoneNumber::class, 'owner_id');  

使用 phone_numbers 表的 owner_id 进行关联。使用的时候,先获取Contact条目,然后使用关联方法获取PhoneNumber对象, 代码是这样的:

 $contact = Contact::first();
$contactPhone = $contact->phoneNumber;  

变量 $contactPhone 就是一个模型对象,可以直接访问其各个属性。有同学会疑问, 这中间是靠什么办法关联获取的呢?都是数据库的条目,一定是走SQL查询了吧?

没错,laravel也的确是这样做的。先查找contacts条目:

 select * from contacts where 1 limit 1;   

然后获取的 owner_id 比如等于47,那么接着查找 phone_numbers 表:

 select * from phone_numbers where owner_id = 47;   

每一条SQL都充分利用索引,可以准确快速地拿到结果。

有了一对一关系,我们能不能从手机号码倒推,反向查询到通讯录条目呢?当然是可以的,这就是 一对一的逆函数 belongsTo

 class PhoneNumber extends Model
{
    public function contact()
    {
        return $this->belongsTo(Contact::class);
    }
}  

与上方的调用关系相同,我们先查找到手机号,然后使用关联函数返回Contact模型:

 $contact = $phoneNumber->contact;  

laravel还有一个高级用法,关联插入新的条目。比如写入一条contact,同时更新phone_number。 我们只需在关联关系基础上,链式调用save方法,传入一个关联模型实例。如果要写入多条的,就传入一个 关联模型实例的数组。

用代码演示一下:

 $contact = Contact::first();
$phoneNumber = new PhoneNumber;
$phoneNumber->number = 123123123;
$contact->phoneNumbers()->save($phoneNumber);  

上面是查询出某条contact,然后更新关联模型的手机号。 这是写入一条,你也可以写入多条:

 $contact->phoneNumbers()->saveMany([PhoneNumber::find(1),PhoneNumber::find(2)]);  

或者知道关联模型字段名的,调用模型的create方法,传入一个数组,用于新建:

 $contact->phoneNumbers()->create(['number' => '123123123']);  

有了一对一的铺垫,我们理解一对多就简单的多了。 例如一个用户有多条通讯录,模型内定义如下:

 class User extends Model
{
    public function contacts()
    {
        return $this->hasMany(Contact::class);
    }
}  

那么使用链式调用关联关系方法是,返回的就是一个 Eloquent Collection,例如:

 $user = User::first();
$usersContacts = $user->contacts;  

是集合就可以充分利用集合的函数方法操作数据集。比如返回所有有效的通讯录:

 $actives = $user->contacts->filter(function ($contact) {
    return $contact->status == 'active';
});  

比如对于Contact模型,加入关联了Order订单模型,且是一对多,将符合条件的订单金额求和, 就可以使用集合的reduce方法累加了:

 $lifetimeValue = $contact->orders->reduce(function ($carry, $order) { return $carry + $order->amount; }, 0);  

一对多也有反向关系,但是比一对一复杂,我们其他篇幅再展开说明。

写在最后

本文通过常用的用户,通讯录,订单,手机号等模型数据,演示了laravel模型的一对一一对多 关联的使用方法。

Happy coding 🙂

文章来源:智云一二三科技

文章标题:3分钟短文:Laravel模型一对一一对多关系真的乱吗?

文章地址:https://www.zhihuclub.com/79693.shtml

关于作者: 智云科技

热门文章

网站地图