首頁 後端開發 php教程 關於PHP的Laravel框架中Eloquent物件關係映射的使用

關於PHP的Laravel框架中Eloquent物件關係映射的使用

Jun 13, 2018 pm 02:13 PM
eloquent laravel php

這篇文章主要介紹了PHP的Laravel框架中Eloquent物件關係映射使用,重點講述了Eloquent的資料模型間關係,需要的朋友可以參考下

零、什麼是Eloquent
Eloquent 是Laravel 的'ORM',即'Object Relational Mapping',物件關係映射。 ORM 的出現是為了幫我們把資料庫的運作變得更方便。

Eloquent 讓一個 'Model類別' 對應一張資料庫表,並且在底層封裝了很多 'function',可以讓 Model 類別非常方便地呼叫。
來看一段如下程式碼:

<?php

class Article extends \Eloquent {

protected $fillable = [];

}
登入後複製

'protected $fillable = [];' 這一行程式碼在這裡沒有任何價值,是generator 自動生成的,在此我們不做討論。

這個類別簡直再簡單不過了,沒有指定命名空間,沒有建構函數,如果那一行沒有意義的程式碼也不算上的話,這個檔案就只有兩個有實際意義的東西: 'Article ' 和'\Eloquent'。沒錯,Eloquent 就是這麼屌炸天,只需要繼承一下 Eloquent 類,就可以乾 'first() find() where() orderBy()' 等非常非常多的事情,這就是面向對象的強大威力。

一、Eloquent 基本用法

廢話不多說,下面我將直接展示 Eloquent 的幾種常見用法的程式碼。

找到id 為2 的文章列印其標題

$article = Article::find(2);

echo $article->title;
登入後複製

找出標題為「我是標題」的文章,並列印id

$article = Article::where(&#39;title&#39;, &#39;我是标题&#39;)->first();

echo $article->id;
登入後複製

查詢出所有文章並循環列印所有標題

$articles = Article::all(); // 此处得到的 $articles 是一个对象集合,可以在后面加上 &#39;->toArray()&#39; 变成多维数组。

foreach ($articles as $article) {

  echo $article->title;

}
登入後複製

在10 ~20 之間的所有文章並列印所有標題

$articles = Article::where(&#39;id&#39;, &#39;>&#39;, 10)->where(&#39;id&#39;, &#39;<&#39;, 20)->get();

foreach ($articles as $article) {

  echo $article->title;

}
登入後複製

#查詢所有文章並循環列印所有標題,按照updated_at 倒序排序

#
$articles = Article::where(&#39;id&#39;, &#39;>&#39;, 10)->where(&#39;id&#39;, &#39;<&#39;, 20)->orderBy(&#39;updated_at&#39;, &#39;desc&#39;)->get();

foreach ($articles as $article) {

  echo $article->title;

}
登入後複製

基礎使用要點
1. 每一個繼承了Eloquent 的類別都有兩個'固定用法' 'Article::find($number)' 'Article: :all()',前者會得到一個帶有資料庫中取出來值的對象,後者會得到一個包含整個資料庫的物件集合。

2. 所有的中間方法如'where()' 'orderBy()' 等都能夠同時支援'靜態' 和'非靜態鍊式' 兩種方式調用,即'Article::where( )...' 和'Article::....->where()'。

3. 所有的'非固定用法' 的調用最後都需要一個操作來'收尾',本片教程中有兩個'收尾操作':'->get()' 和'- >first()'。

二、中間操作流程
Builder 這個單字可以直譯成建構器,但是「中間操作流程」比較容易理解,因為資料庫運算大部分時候都是鍊式運算的。

中間操作流,請看程式碼:

Article::where(&#39;id&#39;, &#39;>&#39;, 10)->where(&#39;id&#39;, &#39;<&#39;, 20)->orderBy(&#39;updated_at&#39;, &#39;desc&#39;)->get();
登入後複製

#這段程式碼的`::where()->where()- >orderBy()` 就是中間操作流程。中間操作流用物件導向的方法來理解,可以總結成一句話:

建立一個對象,並不斷修改它的屬性,最後用一個操作來觸發資料庫操作。
如何找到中間操作流的蛛絲馬跡

中間操作流這個東西,文檔裡幾乎沒有任何有價值的信息,那麼,我們該怎麼找出這個玩意兒呢?很簡單,使用以下程式碼:

$builder = Article::where(&#39;title&#39;, "我是标题")->title;
登入後複製

然後你就會看到下面的錯誤:

2016226161019074.jpg (929×97)

為什麼會出錯?因為 `Article::where()` 了之後依然是 `Builder` 對象,還不是 `Article` 對象,不能直接取 `title`。

「終結者」方法

所謂「終結者」 方法,指的是在N 個中間操作流程方法對某個Eloquent 物件進行加工以後,觸發最終的資料庫查詢操作,得到返回值。

`first()` `get()` `paginate()` `count()` `delete()` 是用的比較多的一些「終結者」 方法,他們會在中間操作流的最後出現,把SQL 打給資料庫,得到回傳數據,經過加工回傳一個Article 物件或是一群Article 物件的集合。

複雜用法範例

Article::where(&#39;id&#39;, &#39;>&#39;, &#39;100&#39;)->where(&#39;id&#39;, &#39;<&#39;, &#39;200&#39;)->orWhere(&#39;top&#39;, 1)->belongsToCategory()->where(&#39;category_level&#39;, &#39;>&#39;, &#39;1&#39;)->paginate(10);
登入後複製

三、模型間關係(關聯)
1.一對一關係

顧名思義,這描述的是兩個模型之間一對一的關係。這種關係是不需要中間表的。

假如我們有兩個模型:User 和Account,分別對應註冊用戶和消費者,他們是一對一的關係,那麼如果我們要使用Eloquent 提供的一對一關係方法,表結構應該是這樣的:

user: id ... ... account_id

account: id ... ... user_id
登入後複製

假設我們需要在User 模型中查詢對應的Account 表的信息,那麼程式碼應該是這樣的。 `/app/models/User.php`:

<?php

class User extends Eloquent {

 

 protected $table = &#39;users&#39;;

 public function hasOneAccount()

 {

   return $this->hasOne(&#39;Account&#39;, &#39;user_id&#39;, &#39;id&#39;);

 }

}
登入後複製

#

然后,当我们需要用到这种关系的时候,该如何使用呢?如下:

$account = User::find(10)->hasOneAccount;
登入後複製

此时得到的 `$account` 即为 `Account` 类的一个实例。

这里最难的地方在于后面的两个 foreign_key 和 local_key 的设置,大家可以就此记住:在 User 类中,无论 hasOne 谁,第二个参数都是 `user_id`,第三个参数一般都是 `id`。由于前面的 `find(10)` 已经锁定了 id = 10,所以这段函数对应的 SQL 为: `select * from account where user_id=10`。

这段代码除了展示了一对一关系该如何使用之外,还传达了三点信息,也是我对于大家使用 Eloquent 时候的建议:

(1). 每一个 Model 中都指定表名

(2). has one account 这样的关系写成 `hasOneAccount()` 而不是简单的 `account()`

(3). 每次使用模型间关系的时候都写全参数,不要省略
相应的,如果使用 belongsTo() 关系,应该这么写:

<?php

class Account extends Eloquent {

 protected $table = &#39;accounts&#39;;

 

 public function belongsToUser()

 {

  return $this->belongsTo(&#39;User&#39;, &#39;user_id&#39;, &#39;id&#39;);

 }

}
登入後複製

2.一对多关系

学会了前面使用一对一关系的基础方法,后面的几种关系就简单多了。

我们引入一个新的Model:Pay,付款记录。表结构应该是这样的:

user: id ... ...

pay: id ... ... user_id
登入後複製

User 和 Pay 具有一对多关系,换句话说就是一个 User 可以有多个 Pay,这样的话,只在 Pay 表中存在一个 `user_id` 字段即可。 `/app/models/User.php`:

<?php

class User extends Eloquent {

 

 protected $table = &#39;users&#39;;

 public function hasManyPays()

 {

  return $this->hasMany(&#39;Pay&#39;, &#39;user_id&#39;, &#39;id&#39;);

 }

}
登入後複製

然后,当我们需要用到这种关系的时候,该如何使用呢?如下:

$accounts = User::find(10)->hasManyPays()->get();
登入後複製

此时得到的 `$accounts` 即为 `Illuminate\Database\Eloquent\Collection` 类的一个实例。大家应该也已经注意到了,这里不是简单的 `-> hasOneAccount` 而是 `->hasManyPays()->get()`,为什么呢?因为这里是 `hasMany`,操作的是一个对象集合。

相应的 belongsTo() 的用法跟上面一对一关系一样:

<?php

class Pay extends Eloquent {

 protected $table = &#39;pays&#39;;

 

 public function belongsToUser()

 {

  return $this->belongsTo(&#39;User&#39;, &#39;user_id&#39;, &#39;id&#39;);

 }

}
登入後複製

3.多对多关系

多对多关系和之前的关系完全不一样,因为多对多关系可能出现很多冗余数据,用之前自带的表存不下了。

我们定义两个模型:Article 和 Tag,分别表示文章和标签,他们是多对多的关系。表结构应该是这样的:

article: id ... ...

tag: id ... ...

article_tag: article_id tag_id
登入後複製

在 Model 中使用:

<?php

class Tag extends Eloquent {

 protected $table = &#39;tags&#39;;

 

 public function belongsToManyArticle()

 {

  return $this->belongsToMany(&#39;Article&#39;, &#39;article_tag&#39;, &#39;tag_id&#39;, &#39;article_id&#39;);

 }

}
登入後複製

需要注意的是,第三个参数是本类的 id,第四个参数是第一个参数那个类的 id。

使用跟 hasMany 一样:

$tagsWithArticles = Tag::take(10)->get()->belongsToManyArticle()->get();
登入後複製

这里会得到一个非常复杂的对象,可以自行 `var_dump()`。跟大家说一个诀窍,`var_dump()` 以后,用 Chrome 右键 “查看源代码”,就可以看到非常整齐的对象/数组展开了。

在这里给大家展示一个少见用法(奇技淫巧):

public function parent_video()

{

  return $this->belongsToMany($this, &#39;video_hierarchy&#39;, &#39;video_id&#39;, &#39;video_parent_id&#39;);

}

public function children_video()

{

  return $this->belongsToMany($this, &#39;video_hierarchy&#39;, &#39;video_parent_id&#39;, &#39;video_id&#39;);

}
登入後複製

对,你没有看错,可以 belongsToMany 自己。
其他关系

Eloquent 还提供 “远层一对多关联”、“多态关联” 和 “多态的多对多关联” 这另外三种用法,经过上面的学习,我们已经掌握了 Eloquent 模型间关系的基本概念和使用方法,剩下的几种不常用的方法就留到我们用到的时候再自己探索吧。

重要技巧:关系预载入
你也许已经发现了,在一对一关系中,如果我们需要一次性查询出10个 User 并带上对应的 Account 的话,那么就需要给数据库打 1 + 10 条 SQL,这样性能是很差的。我们可以使用一个重要的特性,关系预载入:http://laravel-china.org/docs/eloquent#eager-loading

直接上代码:

$users = User::with(&#39;hasOneAccount&#39;)->take(10)->get()
登入後複製

这样生成的 SQL 就是这个样子的:

select * from account where id in (1, 2, 3, ... ...)
登入後複製

这样 1 + 10 条 SQL 就变成了 1 + 1 条,性能大增。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

如何PHP中Laravel框架实现supervisor执行异步进程

PHP的Laravel框架中的event事件操作的解析

以上是關於PHP的Laravel框架中Eloquent物件關係映射的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

解決 Craft CMS 中的緩存問題:使用 wiejeben/craft-laravel-mix 插件 解決 Craft CMS 中的緩存問題:使用 wiejeben/craft-laravel-mix 插件 Apr 18, 2025 am 09:24 AM

在使用CraftCMS開發網站時,常常會遇到資源文件緩存的問題,特別是當你頻繁更新CSS和JavaScript文件時,舊版本的文件可能仍然被瀏覽器緩存,導致用戶無法及時看到最新的更改。這個問題不僅影響用戶體驗,還會增加開發和調試的難度。最近,我在項目中遇到了類似的困擾,經過一番探索,我找到了wiejeben/craft-laravel-mix這個插件,它完美地解決了我的緩存問題。

laravel用戶登錄功能 laravel用戶登錄功能 Apr 18, 2025 pm 12:48 PM

Laravel 提供了一個全面的 Auth 框架,用於實現用戶登錄功能,包括:定義用戶模型(Eloquent 模型)創建登錄表單(Blade 模板引擎)編寫登錄控制器(繼承 Auth\LoginController)驗證登錄請求(Auth::attempt)登錄成功後重定向(redirect)考慮安全因素:哈希密碼、防 CSRF 保護、速率限制和安全標頭。此外,Auth 框架還提供重置密碼、註冊和驗證電子郵件等功能。詳情請參閱 Laravel 文檔:https://laravel.com/doc

laravel有哪些版本 laravel新手版本選擇方法 laravel有哪些版本 laravel新手版本選擇方法 Apr 18, 2025 pm 01:03 PM

在面向初学者的 Laravel 框架版本选择指南中,本文深入探討了 Laravel 的版本差異,旨在協助初學者在眾多版本之間做出明智的選擇。我們將重點介紹每個版本的關鍵特徵、比較它們的優缺點,並提供有用的建議,幫助新手根據他們的技能水準和項目需求挑選最合適的 Laravel 版本。對於初學者來說,選擇一個合適的 Laravel 版本至關重要,因為它可以顯著影響他們的學習曲線和整體開發體驗。

laravel框架安裝方法 laravel框架安裝方法 Apr 18, 2025 pm 12:54 PM

文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

laravel怎麼查看版本號 laravel查看版本號方法 laravel怎麼查看版本號 laravel查看版本號方法 Apr 18, 2025 pm 01:00 PM

Laravel框架內置了多種方法來方便地查看其版本號,滿足開發者的不同需求。本文將探討這些方法,包括使用Composer命令行工具、訪問.env文件或通過PHP代碼獲取版本信息。這些方法對於維護和管理Laravel應用程序的版本控制至關重要。

繼續使用PHP:耐力的原因 繼續使用PHP:耐力的原因 Apr 19, 2025 am 12:23 AM

PHP仍然流行的原因是其易用性、靈活性和強大的生態系統。 1)易用性和簡單語法使其成為初學者的首選。 2)與web開發緊密結合,處理HTTP請求和數據庫交互出色。 3)龐大的生態系統提供了豐富的工具和庫。 4)活躍的社區和開源性質使其適應新需求和技術趨勢。

Laravel如何學習 怎麼免費學習Laravel Laravel如何學習 怎麼免費學習Laravel Apr 18, 2025 pm 12:51 PM

想要學習 Laravel 框架,但苦於沒有資源或經濟壓力?本文為你提供了免費學習 Laravel 的途徑,教你如何利用網絡平台、文檔和社區論壇等資源,從入門到掌握,為你的 PHP 開發之旅奠定堅實基礎。

See all articles