关联查询
关联查询通过表与表之间进行关联和对象化, 更高效的操作数据;将表分为主表和附表,通过外键连接,(外键默认为user_id);常分为一对一、一对多和多对多三种模式。
一对一
一张主表中对应附表中某个字段的属性也只有一个。 一对一分为正向关联和反向关联,即可以通过主表查询附表(hasOne),也可通过附表查询主表(belongsTo)。
- 正向关联
1.创建User模型(主表)
2.创建关联数据库模型Profile(附表)
3.在User模型端去关联Profile数据表
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);//hasOne表示正向一对一查询,参数一表示附表,参数二为外键,默认为
}
}
4.控制器用于测试:
$User=UserModel::find(21);//先找到主表中的客户
return $User->profile->hobby;//得到主表对应附表中,客户的爱好。
修改和新增附表中的字段
$User=UserModel::find(21);
$User->profile->save(['hobby'=>'修改']);//先找到,再修改
$User->profile()->save(['hobby'=>'新增']);//新增,,
- 反向查询
在附表模型中关联主表:
class Profile extends Model
{
public function User()
{
return $this->belongsTo(Profile::class);
}
}
控制器端调用:
$Profile=ProfileModel::find(1);//1是附表中的id
return $Profile->user->name;
- 通过正向模拟反向
$User=UserModel::haswhere('profile',['id'=>1])->find();//profile是User类中的方法
return json($user);
闭包方法更加随意操作附表:
$User=UserModel::haswhere('profile',function($query){
$query->where('profile.id',1)
})->select();
return json($user);
总结:
- hasOne 模式, 适合主表关联附表,在主表模型中建立附表名称的function。
- belongsTo 模式, 适合附表关联主表,在附表模型中建立主表名称的function。
- ->profile 属性方式可以修改附表数据, ->profile()方法方式可以新增附表数据;
- 调用过程中,都先找到对应数据,在进行操作。
一对多
一张主表中对应附表中某个字段的属性有多个。 hasMany 模式, 适合主表关联附表, 实现一对多查询。
在主表中关联附表:
public function profile()
{
return $this->hasMany(Profile::class);}
控制器中调用和一对一一样,但是如果附表中存在多条满足条件的字段,一对一只能显示一条,而一对多可显示多条。
$user = UserModel::find(19);
return json($user->profile);
进一步筛选:结合where使用Profile()方法
return json($user->profile);
return json($user->profile()->select();//推荐
return json($user->profile()->where('id','>',10)->select();
- 使用 has()方法, 查询关联附表的主表内容, 比如大于等于 2 条的主表记录
UserModel::has('profile', '>=', 2)->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();//[]可关联多个
多对多
主表中一个人对应附表中多个岗位,附表中某一种岗位对应主表中多个人。存在中间表。belongsToMany 为多对多关联模式。
- role.php 和 access.php 创建一个空模型即可, 无须创建任何;
- 注意: Role 继承 Model 即可,而中间表需要继承 Pivot;
在主表模型中,设置多对多关联
User表->Access->roles
public function roles()
{
return $this->belongsToMany(Role::class, Access::class);
//belongsToMany('关联模型','中间表',['外键','关联键']);
}
测试
public function many()
{
//得到一个用户:蜡笔小新
$user = UserModel::find(21);
//获取这个用户的所有角色
$roles = $user->roles;
//输出
return json($roles);
- 关联新增,使用roles()方法后,在进行save()或saveAll(), 不但会给 tp_role 新增一条数据, 也会给 tp_access 新增一条;
$user->roles()->save(['type'=>'测试管理员']);
$user->roles()->saveAll([[...],[...]]);
真正需要就是通过用户表新增到中间表关联即可。
$user = UserModel::find(19);
$user->roles()->save(1);//将用户19和角色1新增到中间表,即用户19和角色1关联。