laravel的hasOne,hasMany,belongsTo,belongsToMany,hasOneThrough,hasManyThrough詳解

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()的寫法

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章