模型关联
模型关联操作把数据表的关联关系对象化
封装关联操作比常规的数据库联表操作智能和高效 直观
避免在模型内部使用复杂的
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'); } }
两个模型之间因为参照模型的不同会产生相对的但不一定相同的关联关系
且相对的关联关系只有在需要调用的时候才需要定义
下面是每个关联类型的相对关联关系对照
类型 | 关联关系 | 相对的关联关系 |
---|---|---|
一对一 | hasOne | belongsTo |
一对多 | hasMany | belongsTo |
多对多 | belongsToMany | belongsToMany |
远程一对多 | hasManyThrough | 不支持 |
多态一对一 | morphOne | morphTo |
多态一对多 | morphMany | morphTo |
例如 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; }
大王叫我来巡山1998
建议自己在代码里面完成模型间的关系处理 不 依赖模型关联