3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
Eloquent ORM PHP:7.2 Laravel:5.7 Larvel 提供了 Eloquent ORM,只要透過 Model 就可以簡單且快速的操作資料表。 在開始之前,必須先設定 config/database.php 或 .env 與資料庫連線。 建立 Model 建立 Model 可以透過 Artisan 的指令建立。 # 將 Member 建立在 app/Models 底下 php artisan make:model Models/Member 設定 Model 在建立完成以後,可以針對 Model 進行一些操作設定。 範例 namespace AppModels; // 所有 Model 都繼承這個 class use Illuminate\Database\Eloquent\Model; class Album extends Model { // 設定連線(參考 config/database.php 的連線名稱) protected $connection = 'kkbox'; // 設定資料表名稱 protected $table = 'album'; // 預設 primaryKey 為 id,如果不是的話需要另外設定 protected $primaryKey = 'album_id'; // 關閉 timestamps 控制(預設為開啟) public $timestamps = false; // 將時間格式改成 Seconds since the Unix Epoch protected $dateFormat = 'U'; } Notice:Eloquent 操作時預設會去修改 created_at、updated_at 這兩個時間欄位,如果原本的資料表沒有這兩個欄位,只要將 $timestamps 設成 false 就可以正常運作了。 Model 基本使用 設定完成以後,便可以使用 Model 操作資料表。 透過 Model 取得資料 use App\Models\Album; // 取得資料表所有資訊 $albums = Album::all(); // 轉換成 Array 輸出 $albums->toArray(); // 透過 primary key 搜尋,回傳 Model 物件 $album = Album::find($album_id); // 特定條件搜尋,回傳 Illuminate\Database\Eloquent\Collection 物件 // 只要使用 get() 以後,就會回傳 Collection 物件 $album = Album::where('album_name', '誰明浪子心')->get(); // 取得第一筆資料,回傳 Model 物件 $album = Album::where('album_name', '誰明浪子心')->get(); // 取 10 筆資料 $album = Album::where('status', 'take(10)->get(); // 計算總數 $count = Album::where('status', 'count(); // 如果沒有找到指定資料就 throw exception $album = Album::findOrFail($album_id); $album = Album::where('status', 'firstOrFail(); // 取得包含已經刪除的資料(deleted_at not null) $albums = Album::withTrashed()->get(); 透過 Model 新增、修改、刪除 // Insert $album = new Album; $album->album_name = 'Johnson'; $album->status = 1; $album->save(); // Update $album = Album::find($album_id); $album->name = 'John'; $album->save(); // Delete $album = Album::find($album_id); $album->delete(); // destroy(傳入 Primary key 進行批次刪除) Member::destroy([1, 2, 3]); Mass Assignment 除了逐個欄位修改之外,也可以透過 Mass Assignment 批次修改,但 Model 必須加入 fillable(白名單) 或 guarded(黑名單) 來允許操作。 加入 fillable namespace AppModels; use Illuminate\Database\Eloquent\Model; class Album extends Model { protected $connection = 'kkbox'; protected $table = 'album'; protected $primaryKey = 'album_id'; public $timestamps = false; protected $fillable = [ 'album_name', 'status' ]; } 利用 Mass Assignment 批次操作 // 批次建立 // 因為 test 不在白名單內,因此不會被填入 Album::create([ 'name' => 'Johnson', 'status' => 3, 'test' => 'xxxx' ]); // 多欄位更新 $album = Album::find($album_id); $album->fill([ 'name' => 'TEST' ]); $album->save(); Query Scopes 如果有一些大量重複性的 query,可以在 Model 中建立 Query Scopes,定義常用的規則。 以下就用 Local Scopes 來舉例 定義 Scope namespace AppModels; use Illuminate\Database\Eloquent\Model; class Album extends Model { protected $connection = 'kkbox'; protected $table = 'album'; protected $primaryKey = 'album_id'; public $timestamps = false; protected $fillable = [ 'album_name', 'status' ]; // 定義 scope 必須以 scope 單字為開頭 public function scopeJohnson($query) { return $query->where('name', 'Johnson'); } } 使用 $album = Album::johnson()->get(); Relationships 操作資料表最常見的用法就是不同資料表間的 Join,除了透過 Query Builder 直接 Join 之外,也可以直接在 Model 中建立 Relationships,透過 Simple query 達成相同的效果。 設定 Relationships namespace AppModels; use Illuminate\Database\Eloquent\Model; class Album extends Model { protected $connection = 'kkbox'; protected $table = 'album'; protected $primaryKey = 'album_id'; public $timestamps = false; protected $fillable = [ 'album_name', 'status' ]; // hasOne 代表一對一對應 public function label() { // hasOne('Model', 'foreign_key', 'local_key') // 如果 local_key 沒有填,就是自動對應到 album table 的 Primary key return $this->hasOne('FallZuBallAlbumLabel', 'album_id'); } // hasMany 代表一對多對應 public function songs() { // hasMany('Model', 'foreign_key', 'local_key') // 如果 local_key 沒有填,就是自動對應到 album table 的 Primary key return $this->hasMany('FallZuBallSong', 'album_id'); } // belongsTo 一對一反向對應(Artist Model 是設定 hasOne album) public function artist() { // belongsTo('Model', 'foreign_key') return $this->belongsTo('FallZuBallArtist', 'artist_id'); } } 使用 Eager Loading 取得 Relation 的資料。 範例 // 使用 songs relation Album::with(['songs'])->find($album_id)->toArray(); // 針對 Relation 進行欄位定義 Album::with([ 'songs' => function ($query) { // 自訂 Relation Model 的欄位 // 注意:這邊一定要有選擇兩張 table relation 的相關欄位,不然就會拉不到資料 $query->select(['song_id', 'song_name', 'album_id', 'artist_id']); }, // Relation 的 Model 可以透過 'A.B' 的方式繼續往下 Relation 'songs.artist' ])->find($album_id)->toArray(); 如果想要針對 Relation 的 Model 做判斷,就必須使用 whereHas。 範例 // 撈出有 為何分離 這首歌的專輯 $name = '為何分離'; Album::whereHas('songs', function ($query) use ($name) { $query->where('song_name', $name); })->get()->toArray(); 另外,如果有修改到 relation model 的資料,就不能再使用 save() 儲存,而是使用 push() 範例 // save() 只會針對 Album Model 儲存,而 push() 會把 relation model 中修改的值一併儲存 $album = Album::with(['songs'])->find(2); $album->album_grid = 'album_grid'; $album->songs[0]->song_composer = 'song_composer'; $album->push(); Other Creation Methods Eloquent 也根據實務開發上常見的需求,提供了幾個快速建立、修改方法: firstOrCreate firstOrNew updateOrCreate 這三個方法使用方式基本上都相同,唯一不同的只是使用的情境。 以 firstOrCreate 來說,當你的資料庫沒有該筆資料時,變會自動新建一筆,反之,便會回傳該筆值的 Model Object。 範例 // DB 無資料時建立新資料,並回傳該資料的 Model Object $obj = Test::firstOrCreate(['name' => 'Johnson']); // 因為 DB 已有相同的資料,因此會直接改成 first 取得該 Model Object(不會建新資料) $obj = Test::firstOrCreate(['name' => 'Johnson']); 這是最基本的用法,不過這樣使用會有一個隱性的問題,通常實務上不會只有一個欄位,因此會寫成以下這樣: // 此行會再建一筆新資料 $obj = Test::firstOrCreate([ 'name' => 'Johnson', // DB 以有此名稱 'email' => 'johnsonlu@kkbox.com' // 新資料 'status' => 0 // 新資料 ]); 這樣的寫法,它的執行 SQL 會是: select * from test where (name = 'Johnson' and email = 'johnsonlu@kkbox.com' and status = 0) limit 1 如果原本只是要判斷 name 是否存在,便會造成重複建檔的問題。 事實上,這類型的 method 都可以輸入兩個參數: 用於判斷該資料是否存在 建立資料的附加屬性 因此,上述可以需求寫成: // 用 name 當 key 判斷資料是否存在 $obj = Test::firstOrCreate([ 'name' => 'Johnson' ], [ 'status' => 0 ]); 其他 method 用法 // 如果沒有值,取得一個新的 Model Instance $obj = Test::firstOrNew(['name' => 'Johnson']); // 需要 save() 才會真正建資料 $obj->save(); // 如果有值,就會直接取得該資料的 Model Object $obj = Test::firstOrNew(['name' => 'Johnson']); dd($obj); // 如果沒有值,建一筆新資料,並取得該資料的 Model Object // 如果有值,更新資料後,取得該資料的 Model Object $obj = Test::updateOrCreate([ 'name' => 'Yolanda' ], [ 'status' => 1 ]); Soft Deleting 在大型專案中,通常不太會直接刪除 row data,都是透過特定欄位註記而已。而 Eloquent 也提供此功能。 Notice: 要使用此功能,資料表必須有 deleted_at 欄位。 使用前必須先在 Model 裡使用 Illuminate\Database\Eloquent\SoftDeletes; Model namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Album extends Model { // 使用 SoftDeletes Trait use SoftDeletes; protected $table = 'album'; protected $dateFormat = 'U'; } 這樣使用 delete() 時,Eloquent 就會將時間戳記寫在 deleted_at 欄位( Eloquent 取得資料的條件,預設都會判斷 deleted_at)。 Album::find($album_id)->delete(); EAV 架構快速操作 EAV 架構是很常見的資料表設計模式。但在開發上,資料更新的過程非常繁瑣。 Eloquent 可以透過簡單的小技巧搭配 except() 方法快速操作。 範例 $params = [ [ 'album_id' => 1, 'attribute' => 'album_name', 'value' => '誰明浪子心' ], [ 'album_id' => 1, 'attribute' => 'artist_name', 'value' => '王傑' ] ]; $mapIDs = []; foreach ($params as $columnObj) { $eavObj = AlbumEAV::updateOrCreate([ 'album_id' => $columnObj['album_id'], 'attribute' => $columnObj['attribute'] ], [ 'value' => $columnObj['value'] ]); // 取得有修改或新增的 ID $mapIDs[] = $eavObj->id; } // 取出分母 $originEAV = AlbumEAV::where('album_id', 1)->get(); // 透過 except(),撈出未被更動到的資料 $exceptEav = $originEAV->except($mapIDs); foreach ($exceptEav as $exceptObj) { // 如果要 Overwrite,就可以將沒被更新到的刪除 $exceptObj->delete(); } Categories: Laravel Tags: LaravelPHP 分類 Android AngularJS API Blueprint Chrome Database MySQL DataStructure Docker Editor Vim Firefox Git GitLab Google API Hadoop Language Go Java JavaScript jQuery jQueryChart Node.js Vue PHP Laravel ZendFramework Python Mac Network Cisco DLink Juniper Oauth Server Apache Share Unix FreeBSD Linux WebDesign Bootstrap CSS HTML Wordpress Search 搜尋關鍵字:

本文由blogjohnsonluorg提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦