2.withJoin的特性
2.1 第一個特性
的博文中,闡述了利用withJoin進行關聯查詢的情況。這里補充一個命名特性(經過調試確認)
即關系命名的,必須與模型名保持一致,否則withJoin無法使用。(當這個不滿足時,with仍可使用。大家可以調試確認)
即關系名中的School和Xueqi等必須與關聯模型一致,才能使用withJoin。
2.12第二個特性
withJoin的關聯查詢,只支持單層關聯,不支持多層。
比如:
->withJoin( [ 'canxunDanweiSchool' => function($query){ $query ->withJoin(['dwJibie','xiaojieShangJiDanwei']) ; }, 'canxunpeiyangjihuaXueqi' => function($query) use($src){ $query ->withJoin(['glCategory','pyCategory','xnCategory']) ; }, ]
)
這里可能想表達,"多層關聯,即先關聯到School表,再從school表中多層關聯到Category表。類似的,先關聯到Xueqi,再關聯到Category表。“
注意,此時,使用如下代碼進行單層關聯查詢,是可行的。
->when(count($src['canxunPeiyangjihua_pyCategory']) > 0, function($query) use($src){ $query->where('canxunpeiyangjihuaXueqi.peiyang_category_id', 'in', $src['canxunPeiyangjihua_pyCategory']);
})
但是,無法返回多層關聯數據,即withJoin無法返回二層關聯的glCategory、dwJibie等關系中的任何數據。
返回多層關聯數據,只能用with,而不能用withJoin。詳見博文:
TP6中實現多層關聯,第一個表關聯第二個表查詢出的數據,再關聯第三個表
3.with的特性
雖然前述博文中,with能夠查詢出多層的數據,但是with不支持類似於withJoin的inner Join查詢(關於inner Join查詢概念,請搜索網絡)。即如果將博文
中的withJoin換成with,是無法實現withJoin功能的。
即使在with的代碼中,添加where,那么只能實現的是關聯表中的數據過濾,而不涉及本表,即不能實現join的功能。比如,如下代碼:
->with( [ 'canxunDanweiSchool' => function($query){ $query ->with(['dwJibie','xiaojieShangJiDanwei']) // ->field('id, title, jiancheng')//如果通過field設置輸出字段,會限制關聯查詢dwJibie // ->withField('dwJibie') ; }, 'canxunpeiyangjihuaXueqi' => function($query) use($src){ $query ->with(['glCategory','pyCategory','xnCategory']) // ->when(count($src['canxunPeiyangjihua_pyCategory']) > 0, function($query) use($src){ // $query->where('peiyang_category_id', 'in', $src['canxunPeiyangjihua_pyCategory']); //// ->field('id, title, jiancheng')//如果通過field設置輸出字段,會限制關聯查詢dwJibie //// ->withField('dwJibie') // }) ; }, ] )
其中在關系中添加的where查詢,只會使得關聯表中的數據進行過濾,不會對本表查詢的數據進行where過濾。
比如:表a的某行數據data1,在表b中關聯的某行數據,不滿足where條件,那么返回的數據是,表a中的data1仍然被返回,只是表b中對應的關聯數據被篩選掉。這達不到innerJoin功能。
即無法通過with中的where語句來對本表返回的數據進行篩選。而join是要實現這種功能的。
4.實現多層關聯數據查詢,並在關聯表中實現where功能,inner join到本表。
代碼如下:
// $xxx=Db::query('select id from cj_canxundanwei'); // 整理參數 $src = [ 'school_id' => array() ,'xueqi_id' => array() ,'canxunPeiyangjihua_pyCategory'=> array() //搜索培養大類 ]; $src = array_cover($srcfrom, $src); $src['school_id'] = strToArray($src['school_id']); $src['xueqi_id'] = strToArray($src['xueqi_id']); $src['canxunPeiyangjihua_pyCategory'] = strToArray($src['canxunPeiyangjihua_pyCategory']); // 查詢數據 $data = $this ->with( [ 'canxunDanweiSchool' => function($query){ $query ->with(['dwJibie','xiaojieShangJiDanwei']) // ->field('id, title, jiancheng')//如果通過field設置輸出字段,會限制關聯查詢dwJibie ; }, 'canxunpeiyangjihuaXueqi' => function($query) use($src){ $query ->with(['glCategory','pyCategory','xnCategory']) ; }, ] ) ->when(count($src['school_id']) > 0, function($query) use($src){ $query->where('school_id', 'in', $src['school_id']); }) ->when(count($src['xueqi_id']) > 0, function($query) use($src){ $query->where('xueqi_id', 'in', $src['xueqi_id']); }) ->when(count($src['canxunPeiyangjihua_pyCategory']) > 0, function($query) use($src) { /* * 使用原生SQL語句 */ // Db::query('select id from cj_canxundanwei'); // $a='('; // foreach($src['canxunPeiyangjihua_pyCategory'] as $value){ // $a=$a.(String)$value.','; // } // $a=substr($a,0,strlen($a)-1); // $a=$a.')'; // $xxx=Db::query('select c.id from cj_canxundanwei c INNER JOIN cj_xueqi x ON c.xueqi_id = x.id where x.peiyang_category_id in '.$a); // $ddd=array(); // foreach($xxx as $value){ // array_push($ddd,(String)$value['id']); // } // $query->where('id','in',$ddd); /* * 使用原生SQL語句 */ $sch = new CX; $eee=$sch->withJoin(['canxunpeiyangjihuaXueqi'=>function($query){ $query->field('peiyang_category_id'); },])->where("canxunpeiyangjihuaXueqi.peiyang_category_id",'in', $src['canxunPeiyangjihua_pyCategory']) ->field('Canxundanwei.id')->select(); $query->where('id','in',$eee); }) ->select();
即,只能使用原生sql語句。其中被注釋"使用原生sql語句"注釋掉的代碼中為正確內容。而如下代碼中執行的內容,返回的數據是thinkPHP的collection數據
$sch = new CX; $eee=$sch->withJoin(['canxunpeiyangjihuaXueqi'=>function($query){ $query->field('peiyang_category_id'); },])->where("canxunpeiyangjihuaXueqi.peiyang_category_id",'in', $src['canxunPeiyangjihua_pyCategory']) ->field('Canxundanwei.id')->select();
所以,
$query->where('id','in',$eee);
執行會失敗。
注意,db引用的是think\facade\Db類。
即,只能使用原生sql語句,實現多層關聯數據查詢的同時,同時再實現inner Join的功能。如有其余方法,請評論。