https://laravelacademy.org/post/9699.htmlphp
建議用DB門面直接操做數據庫,由於ORM性能低。數據查詢上面,ORM不會比DB差的,就好比with,是用了sql最基本的拆語句優化。ORM的損耗僅僅是代碼層面的,這已經不算是問題了。html
ORM適用於通常到中等複雜度的查詢,也適用於各類模型操做,好比有一個關係targets,你能夠直接用targets()->delete()等等進行關係數據操做。
ORM中的軟刪除,自動更新時間字段,字段保護,字段類型轉換,都會在一些規範並且系統的工程中讓你受益。laravel
另外DB的場景:一些比較複雜的查詢語句,事務操做,等都須要DB來完成。sql
模型類定義 使用模型類以前,須要在數據庫有對應的數據表,由於模型類就是數據表在面向對象編程語言中的映射。好比咱們前面幾篇教程中用到的 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 屬性爲 false: public $incrementing = false; 若是主鍵不是整型,還能夠設置 $keyType 屬性爲 string: protected $keyType = 'string'; 時間戳 Eloquent 默認約定每張表都有 created_at 和 updated_at 字段(遷移類中 $table->timestamps() 會生成這兩個字段),而且在保存模型類時會自動維護這兩個字段。若是你的數據表裏面不包含這兩個字段,或者只包含一個,都須要設置 $timestamps 屬性爲 false: public $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、max、min 等聚合函數查詢: $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' => 'admin@laravelacademy.org'] ); 有的時候咱們可能須要批量更新模型對應數據表的多條記錄,這能夠藉助查詢構建器來實現: 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 的功能遠不只如此,還支持不少強大的功能,好比批量賦值、軟刪除、查詢做用域設置、模型事件、關聯關係等,下一篇教程開始學院君將帶領你們來逐一瞭解這些高階功能。