ThinkPHP5——模型关联(一对多关联)
关联定义
一对多关联的情况也比较常见,使用hasMany
方法定义,参数包括:
hasMany('关联模型名','外键名','主键名',['模型别名定义']);
例如租客表和宿舍表,一个宿舍有多个租客,宿舍和租客一对多的关系,表结构如下:
#宿舍 CREATE TABLE `apartment` ( `apar_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `apar_name` varchar(40) DEFAULT NULL COMMENT '名称', `apar_type` varchar(20) DEFAULT NULL COMMENT '类型', `apar_price` varchar(30) DEFAULT NULL COMMENT '价格', `apar_sum` int(11) DEFAULT NULL COMMENT '床数', PRIMARY KEY (`apar_id`) ) COMMENT='宿舍'; #租客 CREATE TABLE `client` ( `cli_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `aid` int(11) DEFAULT NULL COMMENT '外键', #房间 `cli_name` varchar(20) DEFAULT NULL COMMENT '姓名', `cli_sex` varchar(20) DEFAULT NULL COMMENT '性别', `cli_phone` varchar(40) DEFAULT NULL COMMENT '电话', `cli_identity` varchar(50) DEFAULT NULL COMMENT '身份证', `cli_reservation` varchar(40) DEFAULT NULL COMMENT '预定房间', PRIMARY KEY (`cli_id`), KEY `Apar_id` (`aid`), CONSTRAINT `client_ibfk_1` FOREIGN KEY (`aid`) REFERENCES `apartment` (`apar_id`) ) COMMENT='租客';
宿舍表的模型用hasMany方法,这样已经关联租客表:
<?php namespace app\demo\model; use think\Model; //宿舍 class Apartment extends Model { //定义关联方法 public function comm(){ //hasMany('租客表名','租客表外键','宿舍主键',['模型别名定义']); return $this->hasMany('client','aid','apar_id'); } }
关联查询
我们可以通过下面的方式获取关联数据:
//方法一:这个需要调用$apr->comm才查顾客表 $apr = Apartment::get(1); $apr->comm;//注意这里不加括号 //方法二:不用调用$apr->comm,预先查租客表 $apr = Apartment::get(1,'comm');
注:comm是一个属性,这里先执行comm()把里面的租客信息封装到comm;comm()是关联模型,comm返回是租客的信息
根据关联条件查询
//根据关联条件查询 $apr = Apartment::get(1); $data = $apr->comm()->where('cli_name','陈芬')->select(); print_r($data); //或者使用getBy $apr = Apartment::get(1); $data = $apr->comm()->getByCliName('陈芬'); print_r($data);
关联聚合查询
//聚合查询,默认查询宿舍的租客人数'>='1的宿舍 $apr = Apartment::has('comm')->select(); //查询宿舍的租客人数'>='3的宿舍 $apr = Apartment::has('comm','>=','3')->where('apar_name','410')->select(); print_r($apr);
也可以查询全部宿舍和全部租客相关联的信息 ,如下:
//方法一:获取全部数据 $apr = Apartment::all(); foreach ($apr as $list) { //$list->comm封装全部租客的信息,一个宿舍有多个租客 foreach ($list->comm as $ac){ echo "姓名:{$ac->cli_name},房号:{$list->apar_name}<br>"; } } //方法二:使用关联预查询功能,有效提高性能。 $apr = Apartment::with('comm')->select(); foreach ($apr as $list) { //$list->comm封装全部租客的信息,一个宿舍有多个租客 foreach ($list->comm as $ac){ echo "姓名:{$ac->cli_name},房号:{$list->apar_name}<br>"; } }
关联新增
//新增,添加一位租客 $apr = Apartment::get(1); $cli = new Client(); $cli->cli_name = "小唐"; $cli->cli_sex = '男'; $cli->cli_phone='1315***'; $cli->cli_identity='4487654334567610'; $cli->cli_reservation='没有'; $apr->comm()->save($cli);
如果想批量新增,如下:
//批量新增租客
$apr = Apartment::get(2); $cli = [ ["cli_name"=>'阿K','cli_sex'=>'男','cli_phone'=>'1315***','cli_identity'=>'448***','cli_reservation'=>'没有'], ["cli_name"=>'小胡','cli_sex'=>'男','cli_phone'=>'1315***','cli_identity'=>'448***','cli_reservation'=>'没有'] ]; $apr->comm()->saveAll($cli);
关联更新
//更新 $apr = Apartment::get(1); $comm = $apr->comm()->getByCliName('陈杨文'); $comm->cli_name='杨文'; $comm->save(); //或者通过update方法更新 $apr = Apartment::get(1); $apr->comm()->where('cli_id',5)->update(['cli_name'=>'陈杨文']);
关联删除
//删除id为13的租客 $apr = Apartment::get(2); $comm = $apr->comm()->getByCliId(13); $comm->delete(); //删除所有的关联数据 $apr = Apartment::get(2); $apr->$comm()->delete();