【ThinkPHP6.x框架】(14)数据库的关联模型

本文详细介绍了PHP ORM中的一对一、一对多、多对多关联方式,包括belongsTo、hasOne和hasMany,以及如何在User和Profile、Role和Access表之间实现不同关联模型的操作,包括查询、修改和删除。
摘要由CSDN通过智能技术生成

对于关联方式,系统提供了9种方案,具体如下:

         上面的例子,我们采用了一对一的关联模型,它还有相对的反向关联;

        下面给出一个例子: 

class Profile extends Model {
    public function user() {
    return $this->belongsTo(User::class); 
    }
}
$profile = ProfileModel::find(1); 
return $profile->user->email;

一对一关联查询

        一张  tp_user表,主键为:id;附属表:tp_profile,建立两个字段:user_id和  hobby,外键是user_id。

hasOne

         hasOne模式,适合主表关联附表,具体设置方式如下:

        hasOne('关联模型',['外键','主键']);

关联模型(必须):关联的模型名或者类名
外键:默认的外键规则是当前模型名(不含命名空间,下同)+_id ,例如  user_id
主键:当前模型主键,默认会自动获取也可以指定传入

return $this->hasOne(Profile::class,'user_id', 'id');

        创建User模型和Profile模型,均为空模型;User模型端,需要关联Profile,具体方式如下:

class User extends Model
{
    public function profile() {
    //hasOne表示一对一关联,参数一表示附表,参数二外键,默认user_id 
    return $this->hasOne(Profile::class,'user_id');
} }

         创建一个控制器用于测试输出:Grade.php:

$user = UserModel::find(21);
return json($user->profile); 
return $user->profile->hobby;

        使用  save()方法,可以设置关联修改,通过主表修改附表字段的值;

$user = UserModel::find(19);
$user->profile->save(['hobby'=>'酷爱小姐姐']);

        ->profile属性方式可以修改数据,->profile()方法方式可以新增数据;

$user->profile()->save(['hobby'=>'不喜欢吃青椒']);

belongsTo

        belongsTo模式,适合附表关联主表,具体设置方式如下:

        belongsTo('关联模型',['外键','关联主键']);

return $this->belongsTo(Profile::class,'user_id', 'id');

关联模型(必须):模型名或者模型类名
外键:当前模型外键,默认的外键名规则是关联模型名+_id
关联主键:关联模型主键,一般会自动获取也可以指定传入

        对于  belongsTo()的查询方案如下:

$profile = ProfileModel::find(1);
return $profile->user->email;

        使用  hasOne()也能模拟  belongsTo()来进行查询;

//参数一表示的是User模型类的profile方法,而非Profile模型类 
$user = UserModel::hasWhere('profile', ['id'=>2])->find(); 
return json($user);

//采用闭包,这里是两张表操作,会导致id识别模糊,需要指明表 
$user = UserModel::hasWhere('profile', function ($query) {
    $query->where('profile.id', 2); 
})->select();
return json($user);

一对多关联查询

hasMany模式

        hasMany模式,适合主表关联附表,实现一对多查询,具体设置方式如下:

        hasMany('关联模型',['外键','主键']);

return $this->hasMany(Profile::class,'user_id', 'id');

关联模型(必须):模型名或者模型类名
外键:关联模型外键,默认的外键名规则是当前模型名+_id
主键:当前模型主键,一般会自动获取也可以指定传入

         使用->profile()方法模式,可以进一步进行数据的筛选;

$user->profile()->where('id', '>', 10)->select();
$user->profile->where('id', '>', 10)

        使用  has()方法,查询关联附表的主表内容,比如大于等于  2条的主表记录;

UserModel::has('profile', '>=', 2)->select();

        使用  hasWhere()方法,查询关联附表筛选后记录,比如兴趣审核通过的主表记录;

UserModel::hasWhere('profile', ['status'=>1])->select();

        使用  save()和  saveAll()进行关联新增和批量关联新增,方法如下:

$user = UserModel::find(19);
$user->profile()->save(['hobby'=>'测试喜好', 'status'=>1]); 
$user->profile()->saveAll([
    ['hobby'=>'测试喜好', 'status'=>1], 
    ['hobby'=>'测试喜好', 'status'=>1]
]);

        使用  together()方法,可以删除主表内容时,将附表关联的内容全部删除;

$user = UserModel::with('profile')->find(227);
$user->together(['profile'])->delete();

多对多关联查询

        首先,我们来看多对多关系的三张表,具体如下:

         tp_user:用户表;tp_role:角色表;tp_access:中间表;access表包含了  user和  role表的关联  id,多对多模式。

        在  User.php的模型中,设置多对多关联,方法如下:

public function roles()
{
    return $this->belongsToMany(Role::class, Access::class); 
}

        在 roles方法中,belongsToMany为多对多关联,具体参数如下:

        belongsToMany('关联模型','中间表',['外键','关联键']);

$this->belongsToMany(Role::class, Access::class, 'role_id', 'user_id');

         role.php和 access.php创建一个空模型即可,无须创建任何。注意,注意:Role继承  Model即可,而中间表需要继承  Pivot;在  user.php中,创建  many()方法,用于测试,查询方式如下:

public function many()
{
    //得到一个用户:蜡笔小新
    $user = UserModel::find(21); 
    //获取这个用户的所有角色
    $roles = $user->roles; 
    //输出这个角色所具有的权限
    return json($roles); 
}

        当我们要给一个用户创建一个角色时,用到多对多关联新增;而关联新增后,不但会给  tp_role新增一条数据,也会给  tp_access新增一条;

$user->roles()->save(['type'=>'测试管理员']);
$user->roles()->saveAll([[...],[...]]);

         一般来说,上面的这种新增方式,用于初始化角色比较合适,也就是说,各种权限的角色,并不需要再新增了,都是初始制定好的。我们真正需要就是通过用户表新增到中间表关联即可;

$user->roles()->save(1);
或:
$user->roles()->save(Role::find(1)); $user->roles()->saveAll([1,2,3]); 
或:
$user->roles()->attach(1);
$user->roles()->attach(2, ['details'=>'测试详情']);

        除了新增,还有直接删除中间表数据的方法:

$user->roles()->detach(2);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值