Object Relational Mapping (ORM) 是一種物件和關聯對映的技術。物件指的是物件導向程式語言中的物件,關聯則是關聯式資料庫,ORM 是一個中間轉換的角色,讓原本必須直接接觸關聯式資料庫的部份,轉換成相對映的物件,這樣就能使用物件來操控資料庫,在開發上會比較直覺,也比較容易使用。在 Laravel 框架中,使用 Eloquent ORM。
Model 預設放在 app/models 目錄下。例如:app/models/Post.php,內容如下:
<?php
class Post extends Eloquent{}
在 Eloquent ORM 中,會自動以 Model 的類別名稱的小寫、複數名稱去找尋對應的資料表,所以 Post 的對應資料表就會是 posts 。
當然,你也可以自行指定資料表的名稱:
<?php
class Post extends Eloquent{
protected $table = "post";
}
Eloquent ORM 也假設每個資料表都有一個 primary key 的欄位叫做 id。當然也可以自行定義 primaryKey 屬性去改變預設的名稱,例如:
protected $primaryKey = "myid";
當你的 Model 建立時,Eloquent ORM 會自動幫你加入兩個欄位 updated_at 和 created_at,這兩個欄位會記錄該筆紀錄的更新時間及建立時間(第一次建立時兩者時間相同)。如果你沒有這個需要,可以告訴 Eloquent ORM 不要建立,將 $timestamps 屬性設為 false 即可:
public $timestamps = false;
$posts = Post::all();
回傳陣列資料。Post 是該 Model 類別的名稱,all() 方法會回傳整個資料表的資料。
$post = Post::find(1);
使用 find() 方法,及參數為 id 的值,回傳 Post 物件。
註:在前一節 Query Builder 中所介紹的方法全都可以在 Eloquent ORM 中找到相同名稱的方法。它們分屬 Illuminate/Database/Query/Builder.php 及 Illuminate/Database/Eloquent/Builder.php 兩個類別,都有實作同樣的方法名稱。
假如你需要在找不到資料時顯示 404 等的錯誤頁面,可以讓 Eloquent ORM 丟出例外,使用
$post = Post::findOrFail(1);
或
$post = Post::where('title', '=', 'abc')->firstOrFail();
findOrFail() 和 firstOrFail() 方法會丟出例外。那丟出的例外要由誰接手處理呢?打開 app/start/global.php 檔案,在最前面加入:
<?php
use Illuminate\Database\Eloquent\ModelNotFoundException;
表示要用到 ModelNotFoundException 這個例外類別。
接著在 Application Error Handler (找註解可看到) 區塊中原本的 App::error 之後加上:
App::error(function(ModelNotFoundException $e)
{
return Response::make('Not Found', 404);
});
這樣 Eloquent ORM 丟出的例外就會以 404 的錯誤頁面 (這裡顯示 'Not Found' 文字)來表示。
如果要自訂錯誤頁面,可以改成
return Response::view('errors.missing', array(), 404);
然後建立 404 的 view,app/views/errors/missing.blade.php:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<span style="font-size:50em; color:#e2e2e2;">404</span>
</body>
</html>
使用 where 來做條件查詢,
$posts = Post::where('id', '>', 1)->get();
傳回陣列。用法都和之前介紹的 Query Builder 均相同。
基於安全的考量,Eloquent ORM 預設是禁止大量指派資料到資料庫中,例如使用迴圈來一次新增很多的資料。如果你有大量指派的需求,必須使用 fillable 屬性:
<?php
class Post extends Eloquent {
protected $fillable = ['title', 'content'];
}
你所指定的 title 及 content 這兩個欄位就允許大量指派。
fillable 如果是白名單,那相反的也可指定某個欄位"不允許"大量指派的黑名單,透過 guarded 屬性:
protected $guarded = ['id'];
這樣 'id' 這個欄位就不允許大量指派。如果要保護所有欄位都不能被大量指派:
protected $guarded = array('*');
new 一個 Model 所代表的類別,就是預備新增一筆資料:
$post = new Post;
$post->title = 'Hello~~';
$post->save();
在新增資料後可以立即取得該筆資料的 id:
$postId = $post->id;
你也可以使用 Create 方法來新增資料:
$post = Post::create(['title' => 'Hello~~'));
前提是,你的 Model 必須設定 fillable 或 guarded 其中一個屬性。
先找到要更新的資料才能更新:
$post = Post::find(1);
$post->title = 'Hi~~';
$post->save();
如果你有使用 timestamps 欄位,而且你只想更新它的時間 (updated_at 欄位),你可以"碰一下":
$post->touch();
$post = Post::find(1);
$post->delete();
或使用 destroy 方法:
Post::destroy(1);
Post::destroy(1,2,3);
參數是 id。