遇見 Laravel 的午後(Part 12)
在這個章節,要介紹 Eloquent ORM ,他是以 Query Builder 為基礎,簡單說就是加強版(強化版),兩者皆是Laravel提供存取資料的方法。
什麼是 Eloquent ORM ?
ORM(Object Relational Mapping)物件和關聯資料庫對應,至物件導向的資料抽象化技術,可能覺得前面這麼長一段,到底在講什麼?簡單的說,就是讓資料庫的每個資料表都對應到屬於自己的Model變成一個物件(Class),也就是Model 跟資料庫的溝通互動(新增、查詢、刪除、修改)。
※ Laravel的相關慣例
- 一個
resource
對應到資料庫(DB)裡的一個資料表(Table) - 一個
model
對應到資料表(Table)裡的一筆資料或一列資料(row)
建立 Eloquent Model
(建立Migration 也一併建立Model,有建立過就可忽略此段)
make:model 後面自訂要對應資料表名稱(資料夾/model名稱 或者 model名稱)。
Model名稱使用英文單數,以大駝峰式命名(Upper Camel Case),首字要大寫
1 | $ php artisan make:model Member |
建立 Model
,也一併建立 migration
。 --migration
可以縮寫成 -m
※ 至於 migration
自動產生,他會如何命名? Laravel 預設命名方式:蛇底式命名(Snake Case)
1 | $ php artisan make:model Member --migration |
專案 > app >
以上Model名稱為 Member
專案 > database > migrations >
資料表名稱為 2020_06_13_103343_create_members_table.php
開啟會員資料表對應的 Eloquent Model
專案 > app > Member.php
1 |
|
定義 Eloquent Model
Model 自己對應自己的資料表,這是 Laravel 機制,但基本上我還是會寫自己對應的table,以免會有出差錯的情形,算是給自己一個心安吧。
但一定會有疑問,如果我 Model 名稱要跟資料表不一樣名稱可不可以?其實是可以的,我們可以將繼承 Model 的 Class 內,將table 指向需要的資料表 protected $table = '資料表';
。
1 |
|
Model 定義關聯的資料表,若沒有定義就會指定為Model 名稱小寫的複數
1 | /** |
定義主鍵。但基本上如果主鍵是id,可以不用做定義。
1 | /** |
是否將有 AUTO INCREMENT 欄位做自動遞增,僅限用在int的欄位。預設為true,設成false為取消。
1 | /** |
定義主鍵型態。主鍵型態有可能是 string
(字串)或是 int
(整數),就像是 Email 或是 id
1 | /** |
設定時間戳記。時間戳記預設為true
,所以使用Seeder 及Factory新增假資料的時候會自動帶入時間。預設為 true,設成false為取消。
1 | /** |
資料庫連線方式。有時候一個專案不只用一個資料庫內容,所以可能會有其他多種資料庫連線方式。專案 > .env
1 | /** |
日期的儲存格式。
1 | /** |
U定義型態可以參考:date - PHP
建立Controller
1 | $ php artisan make:controller MemberController |
開啟 MemberController.php
的檔案
專案 > app > Http > Controllers > MemberController.php
1 |
|
- 引入
Member
的 Model,use App\Member;
,但如果沒做引入,在做操作時前面就要加上 App,例如:App\User::all()
- 在class 裡寫一個
index
的function
接下來要做資料庫的操作。
1 |
|
如何使用 Eloquent Model 操作取得資料?
取得資料表所有資料 all()
Member
為 Model 的類別名稱。all()
為取得所有資料。 其實我們可以用get()
來取代all()
,結果是一樣的。toArray()
將模型轉換成一個陣列。
1 | $datas = Member::all(); |
結果
1 | array:11 [▼ |
取得單一筆資料,且是指定資料表id
的資料 find()
find()
,參數值為資料表的 id
值。
1 | $datas = Member::find(10); |
※ 在上一篇(Part 11)的 Query Builder(查詢建構器)有提到 find()
,而 Eloquent ORM 也有 find()
他們雖然用法一樣,但是他們是走不同的類別,前者是走 Illuminate/Database/Query/Builder.php
,而後者是走 Illuminate/Database/Eloquent/Builder.php
,但方法其實是一樣的。
1 | $datas = Member::findOrFail(10); |
結果
1 | array:11 [▼ |
※ findOrFail()
結果雖然與 find()
是一樣的,但是今天若找不到匹配的資料的時候,find()
只會出現 Error
,而 findOrFail()
會出現404的訊息,Eloquent ORM 會將此狀況拋出例外(Exception)。
※ find()
、findOrFail()
跟 first()
、firstOrFail()
類似,看官們可以參考官方的範例。
條件搜尋 where()
當使用條件搜尋的時候,都是以 get()
取得回傳的 Eloquent Collection 物件。
※ all()
跟 get()
是一樣的,但 where()
後面只能接get()
才會正常執行。
※ 查詢 會員權限 等於 2 的。
1 | $datas = Member::where('category', '2')->get(); |
結果
1 | array:3 [▼ |
查詢第一筆資料 first()
1 | $datas = Member::first(); |
上方查詢第一筆資料,但是如果搭配查詢條件(WHERE)的時候,一旦沒查到,他會丟出一個錯誤,但是Laravel 很貼心,寫了一個跟findOrFail()
一樣的函數就是firstOrFail()
,一旦做了查詢條件,找不到任何資料,他會針對此件事情做一個拋出例外,也就是 404。
以下程式碼,查詢會員權限,但會員權限的資料只到5,所以6是找不到的,所以就拋出例外。
1 | $datas = Member::where('category', '=', 6)->firstOrFail(); |
取得 N 筆資料 take()
1 | $datas = Member::take(3)->get(); |
計算幾筆資料 count()
1 | $datas = Member::count(); |
排序 orderBy()
1 | $datas = Member::orderBy('category','asc')->get(); |
排序方式
- ASC(升冪) = 由小到大
- DESC(降冪) = 由大至小
顯示SQL語法 toSql()
1 | $datas = Member::where('category', '2')->toSql(); |
新增資料 create()
1 | $datas = Member::create([ |
修改資料 update()
1 | $datas = Member::where('m_name','高帥哥')->update(['m_id' => 'M10088']); |
刪除資料 delete()
1 | $datas = Member::where('m_name','高帥哥')->delete(); |
顯示生成的SQL語法 (適用 Query Builder 或 Eloquent ORM)
引入 DB 的檔案
1 | use Illuminate\Support\Facades\DB; |
開啟記錄
1 | DB::connection()->enableQueryLog(); |
資料查詢
1 | $datas = Member::where('category', '2')->get(); |
DB::getQueryLog()
,記錄使用過的 sql 語法,使用 dd() 印出
1 | dd(DB::getQueryLog()); |
查詢結果
1 | array:1 [▼ |
結論
稍微介紹完 Eloquent 的操作與用法,是不是與 Query builder 很像,就說他根本是Query builder 2.0版本,別錯過下一篇,還有你所不知道的內容。
標籤: w3HexSchool
PHP
Laravel
原文作者: Sian
原文鏈接: https://dew31794.github.io/2020/08/02/遇見 Laravel 的午後(Part 12)/
版權聲明: 轉載請註明出處(必須保留作者署名及鏈接)