Laravel關聯模型中has和with區別

本篇文章給你們帶來的內容是關於Laravel關聯模型中has和with區別(詳細介紹),有必定的參考價值,有須要的朋友能夠參考一下,但願對你有所幫助。php

首先看代碼:sql

1數據結構

2spa

3code

4ci

5string

6it

$userCoupons = UserCoupons::with(['coupon' => function($query) use($groupId){io

    return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([table

        'group_id' => $groupId,

    ]);

}])

// 更多查詢省略...

數據結構是三張表用戶優惠券表(user_coupons)、優惠券表(coupons),商家表(corps),組優惠券表(group_coupons) (爲了方便查看,後兩項已去除)

這裏我本意想用模型關聯查出用戶優惠券中屬於給定組gourpId的全部數據(若是爲空該條數據就不返回)。

但有些結果不是我想要的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

array(20) {

  ["id"]=>

  int(6)

  ["user_id"]=>

  int(1)

  ["corp_id"]=>

  int(1)

  ["coupon_id"]=>

  int(4)

  ["obtain_time"]=>

  int(1539739569)

  ["receive_time"]=>

  int(1539739569)

  ["status"]=>

  int(1)

  ["expires_time"]=>

  int(1540603569)

  ["is_selling"]=>

  int(0)

  ["from_id"]=>

  int(0)

  ["sell_type"]=>

  int(0)

  ["sell_time"]=>

  int(0)

  ["sell_user_id"]=>

  int(0)

  ["is_compose"]=>

  int(0)

  ["group_cover"]=>

  string(0) ""

  ["is_delete"]=>

  int(0)

  ["score"]=>

  int(100)

  ["created_at"]=>

  NULL

  ["updated_at"]=>

  NULL

  ["coupon"]=>

  NULL  // 注意返回了coupons爲空的數據

}

記錄中有的coupon有記錄,有的爲空。想一想也是,with只是用sql的in()實現的所謂預加載。不管怎樣主user_coupons的數據都是會列出的。

它會有兩條sql查詢,第一條查主數據,第二條查關聯,這裏第二條sql以下:

1

select `id`, `group_id`, `cover`, `group_number`, `group_cover` from `youquan_coupons` where `youquan_coupons`.`id` in (1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14) and (`group_id` = 1) and `youquan_coupons`.`deleted_at` is null

若是第二條爲空,主記錄的關聯字段就是NULL。

後來看到了Laravel關聯的模型的has()方法,has()是基於存在的關聯查詢,下面咱們用whereHas()(同樣做用,只是更高級,方便寫條件)

這裏咱們思想是把判斷有沒有優惠券數據也放在第一次查詢邏輯中,因此才能實現篩選空記錄。

加上whereHas()後的代碼以下

1

2

3

4

5

6

7

$userCoupons = UserCoupons::whereHas('coupon', function($query) use($groupId){

        return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([

            'group_id' => $groupId,

        ]);

    })->with(['coupon' => function($query) use($groupId){

        return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover');

    }])-> // ...

看下最終的SQL:

1

select * from `youquan_user_coupons` where exists (select `id`, `group_id`, `cover`, `group_number`, `group_cover` from `youquan_coupons` where `youquan_user_coupons`.`coupon_id` = `youquan_coupons`.`id` and (`group_ids` = 1) and `youquan_coupons`.`deleted_at` is null) and (`status` = 1 and `user_id` = 1)

這裏其實是用exists()篩選存在的記錄。而後走下一步的with()查詢,由於此時都篩選一遍了,因此with能夠去掉條件。

顯然區分這兩個的做用很重要,尤爲是在列表中,不用特地去篩選爲空的數據,並且好作分頁。

以上就是Laravel關聯模型中has和with區別(詳細介紹)的詳細內容。

相關文章
相關標籤/搜索