Laravel 學習筆記(16) - 資料庫之 Eloquent ORM

Eloquent ORM

Eloquent ORM 讓資料庫中的每個資料表都對應到 Model,你可以透過 Model 和資料表互動。要定義的模型 (Eloquent Model) 預設放在 app/models 目錄下。例如 app/models/Post.php (字首大寫) ,它的內容如下:
<?php
class Post extends Eloquent{}
在 Eloquent 中,會自動以 Model 的類別名稱的小寫、複數名稱去找尋對應的資料表,所以 Post model 對應的資料表就會是 posts 。

Model 的基本屬性

當然,你也可以指定資料表的名稱:
<?php
class Post extends Eloquent{
    protected $table="posts";
}
你可以把 posts 換成你想要的名稱。Eloquent 也假設每個資料表都有一個 primary key 的欄位叫做 id。當然也可以自行定義 $primaryKey 屬性去改變預設的名稱。

當你的 Model 建立時,Eloquent 會自動幫你加入兩個欄位 updated_atcreated_at,這兩個欄位會記錄該筆紀錄的更新時間及建立時間(第一次建立時兩者時間相同)。如果你沒有這個需要,可以告訴 Eloquent 不要建立:
public $timestamps = false;
$timestamps 屬性設為 false 即可。

取得整個資料表的資料

$posts = Post::all();
回傳的值是陣列。

透過 Primary key 取得一筆紀錄

$post = Post::find(1);
1 是 PK 的值,回傳的值是 Post 物件。
註:在前一節 Query Builder 中所介紹的方法全都可以在 Eloquent 中使用。(它們雖然分屬 Illuminate/Database/Query/Builder.php 及 Illuminate/Database/Eloquent/Builder.php 兩個類別,但是實作同樣的方法名稱)

透過 Primary key 取得一筆紀錄,或丟出例外

假如你需要在找不到資料時顯示 404 等的錯誤頁面,可以讓 Eloquent 丟出例外。
$post = Post::findOrFail(1);
$post = Post::where('title', '=', 'xxx')->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 丟出的例外就會以 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>

使用 Eloquent 查詢

$posts = Post::where('id', '>', 1)->get();
傳回陣列。用法都和之前介紹的 Query Builder 相同。

大量指派 (mass-assignment)

基於安全的考量,Eloquent 預設是禁止大量指派資料到資料庫中。如果你有大量指派的需求,必須指定 $fillable 屬性:
<?php

class Post extends Eloquent{
    protected $fillable = ['title', 'content'];
}
這樣,你所指定的 titlecontent 這兩個欄位就允許大量指派。(有時候要透過程式迴圈來大量新增資料時也會用到)

fillable 如果是白名單,那相反的也可指定某個欄位"不允許"大量指派的黑名單,透過 $guarded 屬性:
protected $guarded = ['id'];
這樣 id 這個欄位就不允許大量指派。如果要保護所有欄位都不能被大量指派:
protected $guarded = array('*');

Insert, Update, Delete

新增 (Insert)

$post = new Post;
$post->title = 'Hello~~';
$post->save();
在新增資料後可以立即取得該筆資料的 id:
$postId = $post->id;
你也可以使用 Create 方法來新增資料:
$post = Post::create(['title' => 'Hello~~'));
前提是,你的 Model 必須設定 fillable 或 guarded 其中一個屬性。

更新 (Update)

$post = Post::find(1);
$post->title = 'Hi~~';
$post->save();
如果你有使用 timestamps 欄位,而且你只想更新它的時間 (updated_at 欄位),你可以"碰一下":
$post->touch();

刪除 (Delete)

找到之後刪了它。
$post = Post::find(1);
$post->delete();
本文網址:http://blog.tonycube.com/2015/01/laravel-16-eloquent-orm.html
Tony Blog 撰寫,轉載時請註明出處及文章連結,謝謝 😀

我要留言

留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。