Eloquent 是 Laravel 提供的 ORM 實現。它將資料庫抽象為物件,這些物件 (也稱為「模型」) 被建立、更新或刪除時,Eloquent 會在資料庫中進行相應的更改。
下圖顯示了一個 Eloquent 的簡單示例,通過建立一個新的 PHP 物件併為其屬性分配值,在表 users
中插入一行:
Eloquent 通過建立資料之間的關係,簡化了複雜資料庫結構的工作。它內建了各種關聯關係:
- 將記錄從一個錶連結到另一個表的另一個記錄(一對一關聯)
- 將記錄從一個錶連結到不同表中的多個記錄(一對多關聯)
- 將一個表中的一些記錄連結到另一個表中的記錄數(多對多關聯)
- 一個表的記錄可以動態連結到許多其他表(多型關聯)
- 更多
資料庫中資料實體之間的這些內建關係幫助開發人員輕鬆的處理資料。 例如,下圖顯示了一個部落格程式中使用者、貼子、評論的資料實體之間關係:
Eloquent 使用「模型」的概念來表示資料庫中的資料,接下來我們看一下它的概念。
Model - 模型
像其他 ORM 實現一樣,Eloquent 的「模型」是一個特殊的類,它表示資料庫中的單個表。 使用「模型」可以以物件的方式來處理資料庫中的資料。
當這些類 (模型) 使用 Eloquent 的功能時,Laravel 會自動進行資料庫的 SQL 查詢並返回結果:
將「模型」視為應用程式使用的物件或實體。 例如,如果應用程式是一個線上商店,那麼它所使用的物件就是產品,訂單,產品類別,使用者等。如果應用程式是 SNS - 物件將是狀態,照片,視訊, 位置,使用者之間的關係等。以這種方式表示實體可以大大簡化資料庫的結構,並使您能夠在應用程式中使用 Eloquent。
定義模型時的約定
通過 Eloquent 的模型處理資料庫表時,Laravel 主要有三個主要假設:
- 表的主鍵是一個名為
id
的無符號自動遞增整型。 - 該表具有
datetime
型別的created_at
和updated_at
欄位以儲存建立時間、更新時間的時間戳。 - 如果模型類為
User.php
,則表名應該稱為users
,即以模型類的蛇形、複數形式名稱來作為資料表的名稱
例如:
模型名 | 表名 |
User | users |
Post | posts |
Comment | comments |
Person | people |
Index | indices |
PostCategory | post_categories |
定義模型名的時候,最好不要使用 Laravel 中已經用到的一些類名,例如:App, Auth, Cache, Config, Controller, Cookie, Crypt, Lang, Route, Event, Log, Schema, File, Mail, Session, Form, Password, View, Hash, Queue, Input, Request 等。
每個模型類對應了資料庫中的一個表,例如有一個部落格程式中的貼子表:
我們這樣定義它:
// app/Post.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {}
接下來就可以通過它來進行資料庫的增、刪、改、查各種操作了。
使用模型
Eloquent 提供了許多方法來運算元據庫。 基本的方法如下:
all() - 取回所有記錄
find($id) - 取回一條記錄
first() - 取回第一條記錄
save() - 將當前模型例項作為新記錄新增到資料庫中
create($data) - 通過資料陣列建立一條新記錄
delete() - 刪除當前記錄
destroy($id) - 刪除主鍵值為 $id 的記錄
與 Query Builder 一樣,Eloquent 的大部分方法可以進行鏈式操作。它們還可以與 Query Builder 交替使用。
假設我們有下面兩個表:
Eloquent 模型的屬性表示模型對應的表的列,模型的屬性表示列的值。例如,如果您想從 posts
表中檢索 ID 為 1 的標題和內容,您可以訪問 Post 模型的 title
和 body
屬性,如下面的圖所示:
Inserting records - 插入記錄
try
Route::get('posts/new', function(){
// Create a new instance of the Post model
$post = new App\Post;
// Assign values to model’s attributes
$post->title = "My first post";
// Assign values to model’s attributes
$post->body = "This post is created with Eloquent";
// Insert the record in the DB
$post->save();
// Display the new record containing the blog post
return $post;
});
Laravel 背後的執行過程如下:
這時就可以發現 Eloquent 與 Query Builder 的區別了:
- 通過模型不需要指定記錄將插入哪個表。
- 通過使用物件而不是執行任何資料庫操作來完成新記錄的建立。
Retrieving records - 檢索記錄
Query Builder 中有 find($id)
和 get()
兩個方法,
Eloquent 另外提供了 all()
和 first()
兩個方法。
使用 Query Builder 的 find() 取回單條記錄
// Retrieve a record with primary key (id) equal to “2”
$comment = Comment::find(2);
// If there is a comment with ID “2”, The $comment variable will contain:
/*
object(Comment)#137 (20) {
["attributes":protected]=> array(5) {
["id"]=>
string(1) "2"
["post_id"]=>
string(1) "1"
["body"]=>
string(17) "My second comment"
...
}
...
}
*/
這個相當於:
Comment::where('id',$id)->get();
使用 Eloquent 的 first() 取回單條記錄
first()
用來檢索第一條記錄:
Route::get('comments/first', function() {
$comment = Comment::where('body', 'like', '%comment%')->first();
});
使用 all() 取回所有記錄
Route::get('comments', function() {
$comments = Comment::all();
});
注意:使用 all() 時,不管它前面有沒有其它限定性的操作,都將返回全部記錄。
使用 get() 取回多條記錄
get()
有以下功能:
- 檢索模型對應表的所有記錄
- 對查詢結果進行過濾、分組、排序
- 檢索特定記錄
取回所有記錄:
Route::get('comments', function() {
$comments = Comment::get();
});
過濾資料:
Route::get('published', function() {
$posts = Post::where('title', 'like', '%Laravel%')->get();
});
指定檢索的列:
Route::get('posts', function() {
$posts = Post::get(['title','body']);
});
/*
object(Illuminate\Database\Eloquent\Collection)#149 (1) {
["items":protected]=> array(1) {
[0]=>
object(Post)#137 (20) {
... ["attributes":protected]=> array(2) {
["title"]=>
string(13) "My first post"
["body"]=>
string(34) "This post is created with Eloquent"
}
...
}
}
*/
Updating records - 更新記錄
可以使用如下步驟來更新記錄:
- 通過在模型上使用
find()
,get()
或first()
來檢索屬於模型的記錄 - 為模型的屬性分配新值
- 在模型上呼叫
save()
來儲存資料庫中的更改
Route::get('posts/update', function() {
$post = Post::find(1);
$post->title = "Updated title";
$post->save();
});
注意:Eloquent 不允許一次性更新多條記錄,如有需要可以使用 Query Builder 的 update() 方法。
Deleting records - 刪除記錄
可以使用 delete()
刪除當前模型例項的記錄:
Route::get('posts/delete', function() {
$post = Post::find(1);
$post->delete();
});
也可以使用 destory($id)
刪除指定 $id
的記錄:
Route::get('posts/destory', function() {
$post = Post::destory(1);
});
有關 Eloquent 的更多知識請參考官方文件:
原創。 所有 Laravel 文章均已收錄至 Github laravel-tips 專案。