2015-02-11 9 views
5

http://laravel.com/docs/4.2/eloquent#dynamic-propertiesNhiều cuộc gọi đến thuộc tính động Eloquent có nhấn cơ sở dữ liệu nhiều lần không?

class Phone extends Eloquent { 

    public function user() 
    { 
     return $this->belongsTo('User'); 
    } 

} 

$phone = Phone::find(1); 

Bây giờ, nếu tôi sau đó làm một cái gì đó như thế này:

echo $phone->user->email; 
echo $phone->user->name; 
echo $phone->user->nickname; 

Will hùng biện thực hiện cuộc gọi cơ sở dữ liệu cho mỗi lần tôi sử dụng ->user sở hữu động? Hoặc là đủ thông minh để bộ nhớ cache người dùng trên cuộc gọi đầu tiên?

+0

Một lần lặp sẽ thực hiện cuộc gọi cho 'Phone' và 'User'. Nhiều lần lặp lại bạn phải tải mong muốn. http://laravel.com/docs/5.0/eloquent#eager-loading – user2094178

+0

http://laravel.com/docs/4.2/eloquent#eager-loading – user2094178

+3

Tôi tin rằng tham chiếu đầu tiên cho '$ phone-> user' sẽ tải mô hình 'Người dùng' hoàn chỉnh với tất cả thuộc tính cục bộ cho mô hình đó. Giả sử rằng 'email',' name' và 'nickname' được lưu trữ trong' Người dùng', thì điều này sẽ chỉ dẫn đến hai truy vấn cơ sở dữ liệu (một cho điện thoại, một truy vấn khác cho người dùng). Hãy dùng thử: sau các câu lệnh này, hãy chạy 'dd (\ DB :: getQueryLog())' để xem các truy vấn chính xác được thực hiện. – bishop

Trả lời

5

Trong ví dụ của bạn, thuộc tính user trên đối tượng $phone sẽ bị tải chậm nhưng sẽ chỉ được tải một lần. Hãy nhớ rằng, khi đối tượng được tải, nó không phản ánh bất kỳ thay đổi nào đối với bảng bên dưới trừ khi bạn tải lại theo cách thủ công mối quan hệ bằng phương pháp load.

Các mã sau minh họa ví dụ:

$phone = Phone::find(1); 

// first use of user attribute triggers lazy load 
echo $phone->user->email; 

// get that user outta here. 
User::destroy($phone->user->id); 

// echoes the name just fine, even though the record doesn't exist anymore 
echo $phone->user->name; 

// manually reload the relationship 
$phone->load('user'); 

// now will show null, since the user was deleted and the relationship was reloaded 
var_export($phone->user); 
+0

Điều này có nghĩa rằng ngay cả khi tôi sử dụng tải mong muốn để có được cùng một dữ liệu tôi vẫn nhận được hai cuộc gọi cơ sở dữ liệu khi tôi tìm nạp chỉ một đối tượng. Hoàn toàn tóm tắt các câu hỏi của tôi về điều này. Cảm ơn bạn. – thomthom

+2

@thomthom Có, tải háo hức sẽ tạo ra tối thiểu hai cuộc gọi cơ sở dữ liệu. Tuy nhiên, nó ngăn chặn vấn đề n + 1. Nếu bạn đã làm '$ phones = Phone :: all();', và sau đó foreach qua tất cả các đối tượng điện thoại và hiển thị tên người dùng, nó sẽ thực hiện một truy vấn để nhận tất cả các điện thoại, và sau đó truy vấn người dùng riêng biệt cho mỗi đơn lặp vòng lặp (n + 1). Tuy nhiên, nếu bạn mong muốn tải bằng cách thực hiện '$ phones = Phone :: with ('user') -> get();', và chạy cùng một foreach, điều đó sẽ chỉ thực hiện 2 cuộc gọi cơ sở dữ liệu, một cho điện thoại và một cho tất cả người dùng có liên quan. – patricus

Các vấn đề liên quan