模型关联

模型关联操作把数据表的关联关系对象化
封装关联操作比常规的数据库联表操作智能和高效 直观

避免在模型内部使用复杂的join查询和视图查询

面向对象 模型的关联是模型的某个属性 如用户的档案关联

// 获取用户模型实例
$user = User::get(1);
// 获取用户档案
$user->profile;
// 获取用户档案中的手机
$user->profile->mobile;

为方便和灵活的定义模型的关联关系 框架选择方法定义而不是属性定义
关联属性对应了模型的(关联)方法
关联属性和模型的数据是动态的 非模型类的实体属性

User模型类中定义了profile方法(mobile属性是Profile模型的属性)

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    public function profile()
    {
        return $this->hasOne('Profile');
    }
}

模型可定义多个不同的关联 增加不同的关联方法即可

必须定义Profile模型(即使是个空模型)

<?php
namespace app\index\model;
use think\Model;
class Profile extends Model
{
}

关联方法返回不同的关联对象
这里的profile方法返回的是HasOne关联对象(think\model\relation\HasOne)实例

访问User模型对象实例的profile属性时 调用profile方法来完成关联查询

PSR-2规范 模型的方法名是驼峰命名的 系统做兼容处理 如果 定义了userProfile关联方法时 在获取关联属性时 下面两种方式都是有效的

$user->userProfile;
$user->user_profile;

推荐关联属性统一使用后者 和数据表的字段命名规范一致
系统自动获取关联属性时采用后者

关联定义是在模型类中添加方法(注意不要和模型的对象属性以及其它业务逻辑方法冲突)
一般情况下无需参数 在方法中指定一种关联关系 如上面的hasOne关联关系
8种关联关系

模型方法关联类型
hasOne一对一
belongsTo一对一
hasMany一对多
hasManyThrough远程一对多
belongsToMany多对多
morphMany多态一对多
morphOne多态一对一
morphTo多态

关联方法的第一个参数是要关联的模型名称
也就是说当前模型的关联模型必须也是已经定义好的个模型

一般不需要使用命名空间 自动使用当前模型的命名空间 如果不同请使用完整命名空间定义

<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
    public function profile()
    {
        // Profile模型和当前模型的命名空间不一致
        return $this->hasOne('app\model\Profile');
    }
}

两个模型之间因为参照模型的不同会产生相对的但不一定相同的关联关系
且相对的关联关系只有在需要调用的时候才需要定义
下面是每个关联类型的相对关联关系对照

类型关联关系相对的关联关系
一对一hasOnebelongsTo
一对多hasManybelongsTo
多对多belongsToManybelongsToMany
远程一对多hasManyThrough不支持
多态一对一morphOnemorphTo
多态一对多morphManymorphTo

例如 Profile模型中就可以定义个相对的关联关系

<?php
namespace app\index\model;
use think\Model;
class Profile extends Model
{
    public function user()
    {
        return $this->belongsTo('User');
    }
}

进行关联查询的时候 也是类似 只是当前模型不同

// 获取档案实例
$profile = Profile::get(1);
// 获取档案所属的用户名称
echo $profile->user->name;

如果需要对关联模型进行更多的查询约束 可在关联方法的定义方法后面追加额外的查询链式方法(忌滥用 且不用实际的查询方法)

// 获取档案实例
$profiles = Profile::where('id', '>', 1)->select();
foreach($profiles as $profile) {    // 获取档案所属的用户名称
    echo $profile->user->name;
}

 

Think 模型关联和Think 模型关联相关