hasOne、hasMany、belongsTo這3個的大致中文意思:
hasOne:有一個,加上主謂語應該是 ,A有一個B
hasMany:有很多,A有很多B
belongsTo:屬於,A屬於B
goods_cate(商品分類表:id,titile),goods(商品表:id,cate_id,name),detail(商品詳情表:id,goods_id,price)
一個商品分類下面有多個商品,所以:goods_cate hasMany goods; 一個商品屬於一個商品分類,所以:goods belongsTo goods_cate
一個商品只有唯一一條商品詳情表,所以:goods hasOne detail; 一條商品詳情表只屬於一個商品,所以:detail hasOne goods
class goods {//goods表
function category() {
return $this->belongsTo('GoodsCate', 'goods_cate表的col', 'goods表的col');
}
function detail() {//方法名隨便起
return $this->hasOne('Detail', 'Detail表的col', ' ');
}
function test1() {//測試上面detail()關係是否奏效
$this->with(['detail' => static function($query){
$query->select('id','good_id','detail_content');//這裏的id是detail表的id。goods_id是外鍵必須被選擇。
}])
->('id', '=', 10) //這裏的id是goods表的id
->get()->toArray();
}
function test2() {//多表字段的模糊查詢
$this->with('detail')->where(
function ($query) use ($keywords) {
$query->whereHas('detail', function ($query_detail) use ($keywords) {
$query_detail->where('content', 'like', '%'.keywords.'%');
}) //查詢關聯表detail的contnet字段
->orWhere('label' , 'like', '%'.keywords.'%');//查詢goods表的label字段
});
}
function test2() {//多表字段的模糊查詢
//如果是inner join,這句必須得加
$query->whereHas('detail', function ($query_detail) use ($args) {
$query_detail->whereNotNull('id');
});
$this->with('detail')->where(
function ($query) use ($keywords) {
$query->whereHas('detail', function ($query_detail) use ($keywords) {
$query_detail->where('content', 'like', '%'.keywords.'%');}) //查詢關聯表detail的contnet字段
->orWhere('label' , 'like', '%'.keywords.'%');//查詢goods表的label字段
});
}
function test3($args) {//多表字段的模糊查詢和其他查詢
//如果是inner join,這句必須得加
$query->whereHas('detail', function ($query_detail) use ($args) {
$query_detail->whereNotNull('id');
});
$query->where('cate_id', '=', 5);
//注意這裏爲了和cate_id=5那個條件保持並列關係,這裏的or得繼續用$query1包起來,(cate_id=5) and (admin like '%xx%' or detail.real_name like '%xx%')
沒有包$query1的話,查詢就會變成這樣:cate_id=5 and admin like '%xx%' or detail.real_name like '%xx%',因爲and優先級高於or,所以查詢就變味了。
$query->where(function ($query1) use ($args) {
$query1->whereHas('detail', function ($query_user) use ($args) {$query_user->where('real_name', 'like', '%'.$args['owner'].'%');})
->orWhere('admin' , 'like', '%'.$args['owner'].'%');
});
}
}
class category {//category表
function goods() {
return $this->hasMany('Goods','','');
}
}
class detail {//detail表
function goods() {
return $this->belongsTo('Goods');
}
}
$user = model('Goods')−>find();
$cate = $user−>category;//注意這裏末尾沒有()
$detail = $user->profile;//注意這裏末尾沒有()
============================================================
class Application {
public function server() {
return $this->hasManyThrough(Server::class, RelApplicationToServerCluster::class, 'application_id', 'server_cluster_id', 'id', 'server_cluster_id')
->where('server_info.status', '=', 0);
}
}
class Server {
public function application() {
return $this->belongsToMany(Application::class, 'rel_application_to_server_cluster', 'server_cluster_id', 'application_id', 'server_cluster_id', 'id', 'key5')
->where('application.status', '=', 0);
}
}
============================================================
hasManyThrough
https://blog.csdn.net/wxq4100798/article/details/81050136
假設from表用a代替,中間表用b,目標表用c,則
$this->hasManyThrough('c模型','b模型',
'a表與b表關聯,在b表中的外鍵名', 'b表與c表關聯,在c表中的外鍵名',
'a表與b表關聯,在a表中的名字', 'b表與c表關聯,在b表中的名字',
);
2張表:
2張表 | model A | model B |
1對1 |
hasOne() 舉例: |
belongsTo() 舉例: |
1對多 |
hasMany() 舉例: |
belongsTo() 舉例: |
3張表(中間b表是映射關係表):
3張表 | model A | model C |
1對1 |
hasOneThrough() |
hasOneThrough() |
1對多 |
hasOneThrough() |
hasManyThrough() |
多對多 |
hasManyThrough() 舉例:hasManyThrough( c表,b表, b表對應的a表col,c表col, a表col,b表對應的c表col ) |
belongsToMany() 舉例:belongsToMany( a表,b表, c表col,b表對應的a表col, b表對應的c表col,a表col ) |
⚠️注意
1、關聯查詢
modelA的hasOne()與modelB的belongsTo() (modelA的hasMany()與modelB的belongsTo())
若只有modelA中用到AB的關聯關係,只需要保留modelA中的hasOne()即可;
若只有modelB中用到AB的關聯關係,只需要保留modelB中的belongsTo()即可;
若modelA和modelB中都用到AB的關聯關係,同時保留modelA中的hasOne()和modelB中的belongsTo()
2、關聯查詢(goods表與detail表的關聯查詢)
(1)select關聯表detail的部分字段
如果with關聯查詢,默認是查詢關聯表的所有字段的。如果想要只選擇部分關聯的表的字段,詳見goods模型類的test1()的寫法
(2)兩表字段的模糊查詢
如果對goods表的label字段或者detail表的content字段做模糊搜索,詳見goods模型類的test2()和test3()的寫法