<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ##### Eloquent 模型關系 `Factories`工廠表 與`Workers`工人表,是一對多關系。 ~~~php // Factory.php class Factory extends Model { public function workers() { return $this->hasMany(Worker::class); } } // Worker.php class Worker extends Model { public function factory() { return $this->belongsTo(Factory::class); } } ~~~ 當我們在控制器中請求時: ~~~php public function index() { $factories = Factory::query()->find(1); } ~~~ 此時執行的 SQL 語句只有一條 ~~~php select * from `factories` where `factories`.`id` = '1' ~~~ 當我們要訪問 Factory 1 的工人時: ~~~php public function index() { $factories = Factory::query()->find(1); $factories->workers; } ~~~ 此時執行的 SQL 語句是 ~~~php select * from `factories` where `factories`.`id` = '1' select * from `workers` where `workers`.`factory_id` = '1' ~~~ 產生了一次額外查詢。 因為 Eloquent 僅處理了對`Factory`模型進行了查詢,并不知道你想要`workers`的關聯數據,所以并沒有為你準備好它,這樣可以避免不必要的查詢,來加快返回效率。 Laravel 中對所有模型關聯關系的訪問,如果沒有使用`with()`提前告訴 Eloquent 你想要關聯的關系,從而進行訪問時,就叫`懶加載`。通常也是`N+1`問題經常會出現的地方。 #### 假如我們要訪問所有工廠的工人呢? ~~~php public function index() { $factories = Factory::query()->get(); // 工廠表有 10 條記錄 foreach($factories as $factory) { $factories->workers; } } ~~~ 這時就會產生`N+1`的的問題,看一下 SQL 語句 ~~~php select * from `workers` where `workers`.`factory_id` = '1' select * from `workers` where `workers`.`factory_id` = '2' ... select * from `workers` where `workers`.`factory_id` = '9' select * from `workers` where `workers`.`factory_id` = '10 ~~~ 產生了 10 次 SQL 查詢,加上本身對所有工廠的查詢,一共 11 次,這就是`N+1`了。 * * * 我為什么用`Facotry`工廠表 和`Workers`工人表來舉例呢?因為我要用更直白的話語來描述。 ~~~php 工廠晚上 5 點下班,工人們都回宿舍休息了。晚上 10 點時,流水線長突然接到上頭指示,來了個急活,需要工人加班來工作。因為工人并不知道晚上要加班,所以都脫衣服上床睡覺了,這個時候線長是不是要把他們挨個都叫起來呀?工人從被窩起來,打著哈欠,一邊穿衣服一邊嘴里罵罵咧咧,然后回到生產線干活,這個過程就是 `懶加載`。 ~~~ 其實`懶加載`并沒有什么壞處,它在執行效率上是最優的。程序只查詢預期中的的數據,并不知道你要訪問它的模型關系,當你需要訪問模型關系時,再去查詢一次就好了。 **但是我們需要注意的是**,當查詢結果不是一個單條記錄 (`Model`),而是多條記錄 (`Collection`) 時,如果這個時候要去訪問`Collection`中每條記錄的模型關系,那就需要使用接下來的`預加載`了。否則就會產生上文的`N+1`的問題。 * * * 還是剛才的查詢,這次使用`with()`預加載工人關系。 ~~~php public function index() { $factories = Factory::query()->with('workers')->get(); // 工廠表有 10 條記錄 foreach($factories as $factory) { $factory->workers; } } ~~~ 此時 SQL 查詢就只有 2 條。 ~~~php select * from `factories` select * from `workers` where `workers`.`factory_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ~~~ 還是上面的工廠例子,再舉一次: ~~~php 工廠接到一筆新訂單,是個急活,廠長周一就通知下去本周六加班,所有工人必須守候在流水線隨時待命,這就叫`預加載`。 ~~~ 工人信息已經準備好了,只等著你去訪問它就可以了。 * * * #### 由此可以得出結論: 當你的查詢結果返回的是一個 單條記錄 (`Model`),此時`懶加載`和`預加載`其實沒有區別,因為每一個模型關系就是一次查詢,所以這里不論是使用`with()`預加載,還是直接使用`懶加載`,對于單條記錄的模型來說,最終 SQL 執行條數都是一樣的。 但當你的查詢結果返回的是多條記錄 (`Collection`) 時,如果要訪問模型關系,就**必須**使用`with()`預加載,否則就會產生`N+1`問題。 * * * #### 那么`load()`是干嘛的? 我們這樣查詢可以嗎? ~~~php public function index() { $factory = Factory::query()->load('workers')->find(1); } ~~~ 結果是肯定不行的 ~~~php BadMethodCallException: Call to undefined method Illuminate\Database\Eloquent\Builder::load() ~~~ 在一個查詢沒有使用`get()`或`find()`返回之前,它都是一個`EloquentBuilder`對象,我們的所有`where()`、`with()`、`whereIn()`、等方法都是在構造查詢語句,但其實并沒有數據被真正的查詢。 當這條語句被執行時,并沒有 SQL 語句被執行。 ~~~php Factory::query()->with('workers'); ~~~ `load()`是模型`Model`才能使用的方法,`EloquentBuilder`是不能使用的。 * * * #### 看一下如何使用`load()`。 ~~~php public function index() { $factory = Factory::query()->find(1); $factory->load('workers'); } ~~~ 此時被執行的 SQL 語句是: ~~~php select * from `factories` where `factories`.`id` = '1' limit 1 select * from `workers` where `workers`.`factory_id` in (1) ~~~ 其實上面的查詢和下面的這句`with()`是一模一樣的: ~~~php public function index() { $factory = Factory::query()->with('workers')->find(1); } ~~~ #### 那么`load()`的使用場景是? 假如我們使用依賴注入的方式來查詢`Factory`,但同時我們還要把`workers`關聯一并返回的時候,就會用到它了。 ~~~php public function index(Factory $factory) { return $factory->load('workers'); } ~~~ `with()`是查詢時一并加載模型關聯,`load()`是先有模型被查詢后,再加載模型的關聯時使用的。
                  <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>

                              哎呀哎呀视频在线观看