1. 程式人生 > >laravel orm進行增刪改查

laravel orm進行增刪改查

 https://laravelacademy.org/post/9699.html

建議用DB門面直接操作資料庫,因為ORM效能低。資料查詢上面,ORM不會比DB差的,就比如with,是用了sql最基本的拆語句優化。ORM的損耗僅僅是程式碼層面的,這已經不算是問題了。

ORM適用於一般到中等複雜度的查詢,也適用於各種模型操作,比如有一個關係targets,你可以直接用targets()->delete()等等進行關係資料操作。
ORM中的軟刪除,自動更新時間欄位,欄位保護,欄位型別轉換,都會在一些規範而且系統的工程中讓你受益。

另外DB的場景:一些比較複雜的查詢語句,事務操作,等都需要DB來完成。

模型類定義
使用模型類之前,需要在資料庫有對應的資料表,因為模型類就是資料表在面向物件程式語言中的對映。比如我們前面幾篇教程中用到的 User 模型和 Post 模型都是這樣,要建立一個模型類,需要使用 make:model 命令:

php artisan make:model Post
注:如果對應的資料表尚未建立,你還可以在建立模型類的同時建立對應的資料庫遷移檔案,通過 php artisan make:model Post -m 即可。如果你想將模型類建立到 app/Models 目錄下,可以這麼執行上述命令 php artisan make:model Models/Post。

接下來我們就是 posts 表對映的 Post 模型為例,來看看預設都有哪些約定。新生成的 Post 模型類如下:

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { // } 裡面什麼東西都沒有,但是我們就可以通過它完成資料表記錄的增刪改查操作了,怎麼做到的?這就是「約定優於配置」的功勞了。下面我們就來看看這些預設的約定。 表名 Eloquent 約定模型類對映表名是將類名由駝峰格式轉化為小寫+下劃線(含多個單詞的話),最後將其轉化為複數形式,比如 Post 對應表名是 posts、PostTag 對應表名是 post_tags 等等。當然,如果你不想遵循這個系統約定的規則,也可以通過手動設定模型類屬性的方式進行自定義,例如:
protected $table = 'articles'; 主鍵 Eloquent 預設假設每張資料表都有一個整型的自增主鍵,其欄位名為 id,如果你的資料表主鍵名不是 id,可以通過 $primaryKey 屬性來指定: protected $primaryKey = 'post_id'; 如果主鍵不是自增的,還可以設定 $incrementing 屬性為 falsepublic $incrementing = false; 如果主鍵不是整型,還可以設定 $keyType 屬性為 stringprotected $keyType = 'string'; 時間戳 Eloquent 預設約定每張表都有 created_at 和 updated_at 欄位(遷移類中 $table->timestamps() 會生成這兩個欄位),並且在儲存模型類時會自動維護這兩個欄位。如果你的資料表裡面不包含這兩個欄位,或者只包含一個,都需要設定 $timestamps 屬性為 falsepublic $timestamps = false; 或者通過 CREATED_AT 和 UPDATED_AT 常量來設定自定義的建立和更新時間欄位: public const CREATED_AT = 'create_time'; public const UPDATED_AT = 'update_time'; 此外,預設時間的儲存格式是 Y-m-d H:i:s,你還可以通過 $dateFormat 屬性來自定義時間戳的格式,該屬性值通過 PHP 的 date() 函式進行解析,所以原則上支援 date 函式支援的所有語法格式,比如將時間設定為 Unix 時間戳: protected $dateFormat = 'U'; 這樣,儲存到資料庫的時間格式就是 Unix 時間戳了,前提是你的 created_at 和 updated_at 欄位是整型,否則會報格式錯誤。 資料庫連線 Eloquent 模型類預設約定的資料庫連線是 config/database.php 中配置的預設連線,正如我們在連線配置教程中所說的那樣,如果應用配置了多個數據庫連線,可以通過 $connection 屬性為模型類指定使用哪個連線: protected $connection = 'connection_name'; 查詢資料 日常開發中,大部分操作都是資料庫中查詢資料,Eloquent 模型了為我們提供了很多方法幫助我們從資料庫中獲取資料。 獲取所有記錄 我們可以通過模型類提供的 all 方法獲取一張表的所有記錄: $posts = Post:all(); 和查詢構建器一樣,該方法返回的也是集合,只不過是模型類集合: 要獲取指定模型類的欄位屬性,遍歷該集合即可: foreach ($posts as $post) { dump($post->title); } 和查詢構建器一樣,如果結果集很大的話,模型類也支援通過 chunk 方法分塊獲取查詢結果: Post::chunk(10, function ($posts) { foreach ($posts as $post) { if ($post->views == 0) { continue; } else { dump($post->title . ':' . $post->views); } } }); 除此之外,在 Eloquent 模型中還可以通過 cursor 方法每次只獲取一條查詢結果,從而最大限度減少記憶體消耗: foreach (Post::cursor() as $post) { dump($post->title . ':' . $post->content); } 獲取指定查詢結果 如果想要指定查詢條件和查詢欄位,可以通過 where 方法和 select 方法來實現: $posts = Post::where('views', '>', 0)->select('id', 'title', 'content')->get(); 對應查詢結果如下: 實際上,Eloquent 模型類底層的查詢也是基於查詢構建器來實現的,你可以在模型類上呼叫所有查詢構建器的 Where 查詢方法,同樣是以流介面的模式構建方法鏈呼叫即可。前面提到的 chunk 和 cursor 方法也適用於這種指定查詢條件的查詢操作。 因為是查詢構建器,所以我們還可以在模型查詢操作中對查詢結果進行排序和分頁: $posts = Post::where('views', '>', 0)->orderBy('id', 'desc')->offset(10)->limit(5)->get(); 對應的返回結果如下: 獲取單條記錄 當然,你也可以通過查詢構建器的方式在模型類查詢中獲取單條記錄: $user = User::where('name', '學院君')->first(); 返回的結果是一個模型類例項: 你可以直接通過 $user->name 這樣的方式訪問模型類例項的屬性。 此外,如果查詢的條件是主鍵 ID 的話,還可以將上述呼叫簡化為通過 find 方法來實現: $user = User::find(1); 返回結果與上面完全一致。 模型類查詢結果為空會返回 null。如果你想要在單條記錄返回結果為空時返回 404 響應(在控制器方法中可能需要用到類似操作),可以通過 firstOrFail 或者 findOrFail 方法在找不到對應記錄時丟擲 404 異常,從而簡化程式碼編寫: $user = User::findOrFail(111); 如果 id=111 的記錄在 users 資料表中不存在,就會返回 404 響應: 獲取聚合結果 Eloquent 模型類同樣支援 count、sum、avg、maxmin 等聚合函式查詢: $num = User::whereNotNull('email_verified_at')->count(); # 計數 $sum = User::whereNotNull('email_verified_at')->sum('id'); # 求和 $avg = User::whereNotNull('email_verified_at')->avg('id'); # 平均值 $min = User::whereNotNull('email_verified_at')->min('id'); # 最小值 $max = User::whereNotNull('email_verified_at')->max('id'); # 最大值 你會發現,如果你掌握了查詢構建器,就等同於掌握了 Laravel 中的所有資料庫查詢操作。只不過將 DB::table 換成對應的模型類而已。 注:除獲取單條記錄之外,ELoquent 模型類查詢返回的結果都是集合類,因此你可以在查詢結果上呼叫集合類的所有方法,還可以自定義模型對應集合類,詳情請檢視對應官方文件。 插入資料 通過 Eloquent 模型類插入記錄到資料庫也比較簡單: $post = new App\Post; $post->title = '測試文章標題'; $post->content = '測試文章內容'; $post->user_id = 1; $post->save(); 建立時間和更新時間欄位由 Eloquent 底層自動幫我們維護(遵循預設約定的話)。執行上面的程式碼就會在資料庫新增一條記錄(我們在 Tinker 中執行上述程式碼): 我們先要建立一個新的 Post 模型例項,然後依次設定需要設定的欄位,最後呼叫 save 方法儲存即可。 此外,Eloquent 還為我們提供了一些快捷的插入方法,比如 firstOrCreate 和 firstOrNew,這兩個方法都會先嚐試通過指定查詢條件在資料庫中查詢對應記錄,如果沒有找到的話,會建立對應模型類的例項,並將查詢條件作為對應欄位值設定到模型屬性上。兩者的區別是 firstOrCreate 方法在設定完模型屬性後會將該模型記錄儲存到資料庫中,而 firstOrNew 不會: $post_1 = Post::firstOrCreate([ 'title' => '測試文章標題1', 'user_id' => 1, ]); $post_2 = Post::firstOrNew([ 'title' => '測試文章標題1', 'user_id' => 1, ]); 不過學院君倒不建議這麼做,感覺還是分開寫程式碼可讀性更好一些,也方便自己去處理一些異常情況。 更新資料 通過模型類更新資料表記錄也很簡單: $post = Post::find(31); $post->title = '測試文章標題更新'; $post->save(); 更新時間 Eloquent 底層會自動幫我們維護,執行上面的程式碼即可完成該 $post 模型對應資料表記錄的更新: 同樣,Eloquent 也為我們提供了快捷的更新方法 updateOrCreate,該方法首先會根據傳入引數對模型對應記錄進行更新,如果發現對應記錄不存在,則會將更新資料作為初始資料插入資料庫,並儲存(同樣也不建議這麼做,除非你的場景特別適合): $user = user::updateOrCreate( ['name' => '學院君'], ['email' => '[email protected]'] ); 有的時候我們可能需要批量更新模型對應資料表的多條記錄,這可以藉助查詢構建器來實現: Post::where('views', '>', 0)->update(['views' => 100]); 刪除資料 通過模型類刪除對應資料表記錄和更新記錄類似,都要先獲取對應操作模型例項,刪除對應記錄更簡單,獲取到模型例項後,直接呼叫其刪除方法即可: $post = Post::find(31); $post->delete(); 這樣,就完成了 id = 31 對應資料表記錄的刪除,你還可以通過 Eloquent 提供的 destroy 方法一次刪除多條記錄,通過陣列傳遞多個主鍵 ID 即可: Post::destroy([1,2,3]); 當然,你也可以通過查詢構建器的方式刪除指定記錄: $user = User::where('name', '學院君')->fisrt(); $user->delete(); 結語 在這篇教程中,我們簡單給大家介紹了 Eloquent 是什麼,以及「約定優於配置」理念在 Eloquent 中的應用,最後還給大家演示瞭如何通過 Eloquent 實現資料庫的增刪改查,當然,Eloquent 的功能遠不僅如此,還支援很多強大的功能,比如批量賦值、軟刪除、查詢作用域設定、模型事件、關聯關係等,下一篇教程開始學院君將帶領大家來逐一瞭解這些高階功能。