<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # ->relationship();與->relationship;的區別 ## 對比 | $user->roles(); | $user->roles; | | --- | --- | | Builder 對象 | Collection(數據集) 或 Model(單條) | * $user->roles()返回的是一個Builder的對象,后面可以跟進任何Builder方法,所以跟進Builder下的create/update/delete也就不奇怪了。 * $user->roles返回的是已經查詢結束的Collection結果集,即使后面跟著的函數名字相同(比如:first、count等),但其實現的原理是完全不一樣的,能在sql中處理的就在sql中處理,給數據集處理增加開銷。 比如: | $user->roles()->count(); | $user->roles->count(); | | --- | --- | | DB::exec('SELECT COUNT(*) FROM role_user WHERE uid = 1'); | count(DB::exec('SELECT * FROM role_user WHERE uid = 1')); | 很明顯前者的性能要優秀的多。 # 善用->relationship(); 在日常開發之中,以下語句可以參考: 創建時間倒序 ~~~ function posts() { return $this->hasMany('App\\Post', 'uid', 'id')->orderBy('created_at', 'DESC'); } ~~~ 取10條 `$user->posts()->limit(10)->get();` 取1條 `$user->posts()->first();` 下面這條語句,除非你的確需要得到所有合集。 不然,SQL會先取出所有數據,再使用PHP的array_slice函數讀取10個,這樣浪費了大量性能。 ~~~ $user->posts->slice(0, 10); ~~~ # with load with,load一個更大的性能提升 ## with 對比 不使用with ~~~ $posts = Post::where('created_at', '>' ,Carbon::today())->get(); //取出今天的所有帖子 foreach($posts as $post) echo '作者', $post->user->username; ~~~ 使用with ~~~ $posts = Post::with(['user'])-$posts = Post::with(['user'])->where('created_at', '>' ,Carbon::today())->get(); //取出今天的所有帖子 foreach($posts as $post) echo '作者', $post->user->username; ~~~ 可能看不出來兩者的區別,此處我們換算成PHP、SQL語句看一下 ~~~ // $posts = SELECT * FROM `posts` WHERE `created_at` > Carbon::today() $posts = Post::where('created_at', '>' ,Carbon::today())->get(); foreach($posts as $post) // $post->user = SELECT * FROM `users` WHERE `id` = $post->uid echo '作者', $post->user->username; ~~~ 使用with的情況 ~~~ // $posts = SELECT * FROM `posts` WHERE `created_at` > Carbon::today() // $uid_list = $posts->pluck('uid'); // $users = SELECT * FROM `users` WHERE `uid` IN ($uid_list) // foreach($posts as $post) $post->user = $users[$post->uid]; $post = Post::with(['user'])->where('created_at', '>' ,Carbon::today())->get(); foreach($posts as $post) // 此處并未查詢數據庫 echo '作者', $post->user->username; ~~~ 從上例可以看出, * 沒有使用with時,對user的訪問,循環多少次,就SQL請求多少次; * 使用with時,只對user查詢一次,性能提升了非常明顯。 ## with下級relationship 使用.查詢下級relationship$user->posts()->comments() ~~~ User::with('posts.comments'); ~~~ ## with,Builder對象 取出所有用戶,更新時間倒序;以及返回對應的用戶組 ~~~ $users = User::with(['posts' => function($query) { $query->orderBy('updated_at', 'DESC'); }, 'roles'])->get(); ~~~ 以下誤區需要注意: 下例開發者的本意是每個用戶取出5條,其實系統是整個posts只取出5條,最后分配到每個User的就更少了,這很明顯不符合開發者初愿,但是就目前來說并無優秀的解決辦法。 ~~~ $users = User::with(['posts' => function($query) { $query->limit(5); }])->get(); ~~~ ## load,延遲加載 load,和with的區別是: * with是在組合Builder語句時就開始執行relationship * load在Builder已經執行之后的relationship加載 **注意這個load(),這是對collection用的;** ~~~ $users = User::all(); if (someCondition) { $users->load(['posts' => function($query) { $query->limit(5); }, 'roles']); } ~~~ # has whereHas orWhereHas withCount > haswhereHasorWhereHas其實是對JOIN語句的一個簡化封裝 ## 評論數量> 0的帖子 ~~~ $posts = Post::has('comments')->get(); ~~~ ## 評論數量> 3的帖子 ~~~ $posts = Post::has('comments', '>=', 3)->get(); ~~~ ## 使用.查詢下級relationship 比如關系是:$post->comment()->votes(); ~~~ $posts = Post::has('comments.votes')->get(); ~~~ ## 指定條件的評論的數量> 0的帖子 ~~~ $posts = Post::whereHas('comments', function ($query) { $query->where('content', 'like', 'foo%'); })->orWhereHas(...)->get(); ~~~ ## 返回relationship的數量,字段為:RELATIONNAME_count ~~~ $posts = Post::withCount(['votes', 'comments' => function ($query) { $query->where('content', 'like', 'foo%'); }])->get(); echo $posts[0]->votes_count; echo $posts[0]->comments_count; ~~~ # empty 與 isset ## empty 我們以調取用戶avatar為例 ~~~ if (empty($user->avatar)) //常規判斷 ~~~ 程序員希望是用empty測試avatar是否有記錄,但是他卻忽略了empty并不是函數,而是php的一種特殊語法結構。 empty只能檢查變量是否為空,而不是函數(PHP 7.0以下), $user->avatar在從未讀取的情況下,會先去讀取__get方法實現,__get會依次調取getAttribute()、getRelationValue()來實現,此時程序已經終止了繼續,然后返回true, 除非: ~~~ $user->avatar; // 先讀取一次,Model中的$relations['avatar']已經被填充數據 if (empty($user->avatar)) //此時才會有true/false ~~~ ## isset isset 的實現邏輯與empty類似,但是 ~~~ # laravel\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php 3405 行 public function __isset($key) { if (isset($this->attributes[$key]) || isset($this->relations[$key])) { return true; } if (method_exists($this, $key) && $this->$key && isset($this->relations[$key])) { return true; } return $this->hasGetMutator($key) && ! is_null($this->getAttributeValue($key)); } ~~~ Model中已經實現了__isset方法,并檢查了$this->relations 所以,請使用isset代替empty
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看