摘要:從屬關聯關系更新關聯使用方法,該方法會在子模型設置外鍵移除關聯的時候,使用方法。使得這項操作變得簡單,只需要添加包含關聯關系名稱的屬性到子模型即可觸發的所有關聯關系關聯關系更新時,所屬模型將也會更新其值
Laravel中Eloquent ORM 關聯關系的操作 關聯數據 定義關聯關系
一對一
hasOne("AppPhone"); // 外鍵應該在父級上有一個與之匹配的id(或者自定義 $primaryKey) // return $this->hasOne("AppPhone", "foreign_key"); // 用User的local_key,匹配Phone的foreign_key // return $this->hasOne("AppPhone", "foreign_key", "local_key"); } } $phone = User::find(1)->phone; // 獲取用戶的手機模型
相對的關聯
belongsTo("AppUser"); // return $this->belongsTo("AppUser", "foreign_key"); // return $this->belongsTo("AppUser", "foreign_key", "other_key"); } } $user = Phone::find(1)->user; // 查詢phone的id=1對應的user $user = Phone::where("number","188**")->first()->user; // 查詢電話為188的用戶
一對多
class User extends Model{ // 獲取文章 public function article() { return $this->hasMany("AppComment"); // return $this->hasMany("AppComment", "foreign_key"); // return $this->hasMany("AppComment", "foreign_key", "local_key"); } } $articles = User::find(1)->article; // 返回 userid為1 的所有文章 $article = User::find(1)->article()->where("title", "aa")->first(); // 返回某一篇
一對多(逆向)
class Article extends Model{ public function user() { return $this->belongsTo("AppUser"); // return $this->belongsTo("AppPost", "foreign_key"); // return $this->belongsTo("AppPost", "foreign_key", "other_key"); } } $user = Article::find($id)->user; // 返回文章的作者
多對多
需要三張數據表:users、roles 和 role_user,
role_user 表為關系表,默認按照關聯模型名的字母順序命名,并且包含 user_id 和 role_id 兩個列。
class User extends Model{ /** * 用戶角色 */ public function roles() { //默認去role_user查找關系 // return $this->belongsToMany("AppRole"); return $this->belongsToMany("AppRole","role_users"); // 定義鍵值 // return $this->belongsToMany("AppRole", "user_roles", "user_id", "role_id"); } } $roles = User::find(1)->roles; // 返回 [{"id":1,"name":"SuperManager","pivot":{"user_id":1,"role_id":1}},{"id":2,"name":"Manager","pivot":{"user_id":1,"role_id":2}}] $roles = User::find(1)->roles()->orderBy("name")->get(); // 條件約束
注意我們獲取到的每一個 Role 模型都被自動賦上了 pivot 屬性。該屬性包含一個代表中間表的模型,并且可以像Eloquent 模型一樣使用。
如果你的 pivot 表包含額外的屬性,必須在定義關聯關系時進行指定:
return $this->belongsToMany("AppRole")->withPivot("column1", "column2");
如果你想要你的 pivot 表自動包含created_at 和 updated_at 時間戳,在關聯關系定義時使用 withTimestamps 方法:
return $this->belongsToMany("AppRole")->withTimestamps();
過中間表字段過濾關聯關系
return $this->belongsToMany("AppRole")->wherePivot("approved", 1); return $this->belongsToMany("AppRole")->wherePivotIn("priority", [1, 2]);關聯查詢
存在的關聯查詢
// 獲取所有至少有一條評論的文章... $posts = AppPost::has("comments")->get(); 你還可以指定操作符和數目來自定義查詢: // 獲取所有至少有三條評論的文章... $posts = Post::has("comments", ">=", 3)->get(); 還可以使用”.“來構造嵌套 has 語句,例如,你要獲取所有至少有一條評論及投票的文章: // 獲取所有至少有一條評論獲得投票的文章... $posts = Post::has("comments.votes")->get(); 如果你需要更強大的功能,可以使用 whereHas 和 orWhereHas 方法將 where 條件放到 has 查詢上,這些方法允許你添加自定義條件約束到關聯關系條件約束,例如檢查一條評論的內容: // 獲取所有至少有一條評論包含foo字樣的文章 $posts = Post::whereHas("comments", function ($query) { $query->where("content", "like", "foo%"); })->get();
無關聯結果查詢
// 獲取所有沒有評論的博客文章 $posts = AppPost::doesntHave("comments")->get(); // 檢查評論內容: $posts = Post::whereDoesntHave("comments", function ($query) { $query->where("content", "like", "foo%"); })->get();
統計關聯模型
如果你想要在不加載關聯關系的情況下統計關聯結果數目,可以使用 withCount 方法,該方法會放置一個 {relation}_count 字段到結果模型
$posts = AppPost::withCount("comments")->get(); foreach ($posts as $post) { echo $post->comments_count; } // 添加約束條件到查詢一樣來添加多個關聯關系的“計數”: $posts = Post::withCount(["votes", "comments" => function ($query) { $query->where("content", "like", "foo%"); }])->get(); echo $posts[0]->votes_count; echo $posts[0]->comments_count; // 為關聯關系計數結果設置別名,從而允許在一個關聯關系上進行多維度計數: $posts = Post::withCount([ "comments", "comments AS pending_comments" => function ($query) { $query->where("approved", false); } ])->get(); echo $posts[0]->comments_count; echo $posts[0]->pending_comments_count;渴求式加載
當以屬性方式訪問數據庫關聯關系的時候,關聯關系數據是“懶惰式加載”的,這意味著關聯關系數據直到第一次訪問的時候才被加載。
$books = AppBook::all(); foreach ($books as $book) { echo $book->author->name; } // 該循環要執行26次查詢:1次是獲取書本身,剩下的25次查詢是為每一本書獲取其作者。
$books = AppBook::with("author")->get(); foreach ($books as $book) { echo $book->author->name; } // 在該操作中,只執行兩次查詢即可: // select * from books // select * from authors where id in (1, 2, 3, 4, 5, ...)
渴求式加載多個關聯關系
$books = AppBook::with("author", "publisher")->get();
嵌套的渴求式加載
// 加載所有書的作者及所有作者的個人聯系方式: $books = AppBook::with("author.contacts")->get();
帶條件約束的渴求式加載
// 加載 title 包含 first 的文章 $users = AppUser::with(["posts" => function ($query) { $query->where("title", "like", "%first%"); }])->get(); // 加載按created_at倒序的的文章 $users = AppUser::with(["posts" => function ($query) { $query->orderBy("created_at", "desc"); }])->get();
懶惰渴求式加載
$books = AppBook::all(); if ($someCondition) { $books->load("author", "publisher"); } // 設置更多的查詢條件到渴求式加載查詢上,可以傳遞一個閉包到 load 方法: $books->load(["author" => function ($query) { $query->orderBy("published_date", "asc"); }]);插入 & 更新關聯模型
save 方法
$comment = new AppComment(["message" => "A new comment."]); $post = AppPost::find(1); $post->comments()->save($comment); // save 方法會自動添加 post_id 值到新的Comment 模型。
保存多個關聯模型,可以使用 saveMany 方法:
$post = AppPost::find(1); $post->comments()->saveMany([ new AppComment(["message" => "A new comment."]), new AppComment(["message" => "Another comment."]), ]);
create方法
該方法接收屬性數組、創建模型、然后插入數據庫。save 和 create 的不同之處在于 save 接收整個 Eloquent 模型實例而 create 接收原生 PHP 數組:
使用 create 方法之前確保先瀏覽屬性批量賦值文檔。
$post = AppPost::find(1); $comment = $post->comments()->create([ "message" => "A new comment.", ]);
從屬關聯關系
更新 belongsTo 關聯, 使用associate 方法,該方法會在子模型設置外鍵:
$account = AppAccount::find(10); $user->account()->associate($account); $user->save();
移除 belongsTo 關聯的時候,使用dissociate 方法。該方法會設置關聯關系的外鍵為 null:
$user->account()->dissociate(); $user->save();多對多關聯 的 附加/分離
假定一個用戶可能有多個角色,同時一個角色屬于多個用戶,要通過在連接模型的中間表中插入記錄附加角色到用戶上,可以使用 attach 方法:
$user = AppUser::find(1); $user->roles()->attach($roleId); // 以數組形式傳遞額外被插入數據到中間表: $user->roles()->attach($roleId, ["expires" => $expires]);
移除一個多對多關聯記錄,使用 detach 方法。detach 方法將會從中間表中移除相應的記錄;
但是,兩個模型在數據庫中都保持不變:
// 從指定用戶中移除角色... $user->roles()->detach($roleId); // 從指定用戶移除所有角色... $user->roles()->detach();
接收數組形式的 ID 作為輸入:
$user = AppUser::find(1); $user->roles()->detach([1, 2, 3]); $user->roles()->attach([1 => ["expires" => $expires], 2, 3]);
同步關聯
sync 方法接收數組形式的 ID 并將其放置到中間表
// 任何不在該數組中的 ID 對應記錄將會從中間表中移除 $user->roles()->sync([1, 2, 3]); // 還可以和 ID 一起傳遞額外的中間表值: $user->roles()->sync([1 => ["expires" => true], 2, 3]); // 如果不想要脫離存在的ID,可以使用syncWithoutDetaching 方法: $user->roles()->syncWithoutDetaching([1, 2, 3]);
切換關聯
// 如果當前沒有附加,則附加:如果給定ID當前被附加,則取消附加 $user->roles()->toggle([1, 2, 3]);
在中間表上保存額外數據
// 接收額外中間表屬性數組作為第二個參數: AppUser::find(1)->roles()->save($role, ["expires" => $expires]);
更新中間表記錄 updateExistingPivot
// 更新中間表中已存在的行,接收中間記錄外鍵和屬性數組進行更新 $user = AppUser::find(1); $user->roles()->updateExistingPivot($roleId, $attributes);觸發父級時間戳
當一個模型屬于另外一個時,子模型更新時父模型的時間戳也被更新將很有用
例如,當 Comment 模型被更新時,你可能想要”觸發“更新其所屬模型 Post 的updated_at 時間戳。Eloquent 使得這項操作變得簡單,只需要添加包含關聯關系名稱的 touches 屬性到子模型即可:
class Comment extends Model{ // 觸發的所有關聯關系 protected $touches = ["post"]; // 關聯關系 public function post() { return $this->belongsTo("AppPost"); } }
更新 Comment 時,所屬模型 Post 將也會更新其 updated_at 值
$comment = AppComment::find(1); $comment->text = "Edit to this comment!"; $comment->save();
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30780.html
摘要:是什么是一個,全稱為,翻譯為對象關系映射如果只把它當成數組庫抽象層那就太小看它了。所謂對象,就是本文所說的模型對象關系映射,即為模型間關系。至此,深入理解系列文章到此結束。 原文發表在我的個人網站:深入理解 Laravel Eloquent(三)——模型間關系(關聯) 在本篇文章中,我將跟大家一起學習 Eloquent 中最復雜也是最難理解的部分——模型間關系。官方英文文檔中...
摘要:關聯關系查詢在中,所有的關系都是使用函數定義的,可以在不執行關聯查詢的情況下獲取關聯的實例。 關聯關系 One To One 假設User模型關聯了Phone模型,要定義這樣一個關聯,需要在User模型中定義一個phone方法,該方法返回一個hasOne方法定義的關聯
摘要:軟刪除當模型被軟刪除后,它們并沒有真的從數據庫刪除,而是在模型上設置一個屬性并插入數據庫,如果模型有一個非空值,那么該模型已經被軟刪除了。 Laravel 中Eloquent ORM 相關操作 定義 操作 獲取(查詢) 獲取集合,(查詢列表) 返回值是 IlluminateDatabaseEloquentCollection 的一個實例 獲取所有的數據 use AppUser; $us...
摘要:在中要想在數據庫事務中運行一組操作,則可以在中使用方法。如果在事務的閉包內拋出異常,事務將會被自動還原。 Description 在Laravel中要想在數據庫事務中運行一組操作,則可以在 DB facade 中使用 transaction 方法。如果在事務的閉包內拋出異常,事務將會被自動還原。如果閉包運行成功,事務將被自動提交。你不需要擔心在使用 transaction 方法時還需要...
摘要:模型資料庫遷移儲存紀錄在及之間建立關聯在及之間建立關聯取得紀錄取得取得一對多關聯示例細節在此示例中,我們有兩個模型小偷和車,和兩張表和。業務規則小偷可以偷走多輛車。關系圖關聯詳情關聯表應該保存駕駛員和汽車。 showImg(https://segmentfault.com/img/remote/1460000016043938); 一張 Laravel’s Eloquent ORM 5...
閱讀 2256·2021-11-25 09:43
閱讀 3124·2021-10-14 09:42
閱讀 3484·2021-10-12 10:12
閱讀 1526·2021-09-07 10:17
閱讀 1901·2019-08-30 15:54
閱讀 3181·2019-08-30 15:54
閱讀 1550·2019-08-30 15:53
閱讀 1908·2019-08-29 11:21