目錄
简介
基本概念
一对一
要点:反复观察图!
定义模型
定义User模型
定义Phone模型
数据表
关系查询
模型关系方法查询
动态属性查询
关系绑定和解除
一对多
反绑
多对多
对中间表的操作
sync()方法
Has Many Through(跨表一对多)
Polymorphic Relations(belongsTo多态)
关于绑定和解绑
关于解绑,dissociate()也不适用用于morphTo();所以,只能把Photo实例删除!!删除了就没任何关系了(因为没有中间表)
Many To Many Polymorphic Relations(belongsToMany多态)
Eager Loading(预加载)
Eager Loading可以极大的缓解数据库查询压力,是性能优化的重要手段!
Eager Loading 多个关系
嵌套 Eager Loading
有条件的 Eager Loading
Lazy Eager Loading
跨模型更新时间戳
首頁 後端開發 php教程 Laravel 5.1 文档攻略--Laravel Eloquent ORM最强大也是最难理解的部分:数据关系

Laravel 5.1 文档攻略--Laravel Eloquent ORM最强大也是最难理解的部分:数据关系

Jun 20, 2016 pm 12:33 PM

简介

其实大家都知道,数据表之间都是可以关联的,Eloquent ORM是数据模型操作代替表操作,那么表的关联查询,在Eloquent这里也就是模型间的关联查询,这就是本章的主要内容;

Eloquent一个支持以下6种表间关系:

  • One To One(一对一)

  • One To Many(一对多)

  • Many To Many(多对多)

  • Has Many Through(跨表一对多)

  • Polymorphic Relations(belongsTo多态)

  • Many To Many Polymorphic Relations(belongsToMany多态)

前三个关系是什么就不多解释了(请自行百度),这个地方需要很多耐心,努力让自己习惯对象思维,暂时先不要用sql,练一段时间就会发现非常好用;

当然,也有人吐槽Eloquent由于过于强大,造成每次加载都带一大堆东西,影响效率(实际没啥影响,不服的拿数据跟我说),但是在代码的编写效率,可读性,可维护性上可以说是质的飞跃,所以还是强烈建议优先使用。

这一章我是学得最早,但是教程是写的最晚的,因为各种关系比较复杂,好在我是做产品出身,应该可以把复杂的事情解释清楚,下面就让我们来认识一下这个星球上最强大的ORM:Eloquent

基本概念

先看看是怎么使用的吧:

$user->posts()->where('active', 1)->get();
登入後複製
登入後複製

这个就是通过 $user 对象查出他一共发布了多少篇文章(状态为已发布的)。

我们看到 posts() 在这里是 $user 的一个方法,所以要使用关联查询,得先在 $user 模型里定义关系(方法);

一对一

从这张图中,我们可以看到要使用Eloquent 模型关系,第一步要在模型里定义模型关系,第二步数据库要准备正确的表;第三部分使用 查询的方法,第四部分是使用绑定和解除绑定的方法,我们后续的模型关系都按照这个流程理解和解释;

要点:反复观察图!

定义模型

定义User模型

namespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{        public function phone()    {        return $this->hasOne('App\Phone');    }}
登入後複製

定义Phone模型

namespace App;use Illuminate\Database\Eloquent\Model;class Phone extends Model{    public function user()    {        return $this->belongsTo('App\User');    }}
登入後複製

注意:定义模型的时候方法名注意单复数,“一”就用单数,“多”就用复数,这样不容易混淆搞错。 hasOne() 类似这个关系绑定方法有很多,需要在使用中慢慢熟悉,注意观察。

数据表

主要是注意,外键和中间表这些东西,本例中没有中间表;

关系查询

模型关系方法查询

$user->posts()->where('active', 1)->get();
登入後複製
登入後複製

这就是模型方法查询, $user->posts() 这里查出来是个DQB对象,后面可以接各种数据库查询方法;

动态属性查询

$user->posts;
登入後複製

你可以把关系当做属性用,直接查出来一个collection集;缺点是后面不能跟DQB方法了。

这两种方法都很常用,酌情使用;(下同,不再解释)

关系绑定和解除

通用的绑定方法就是save();

通用的解除方法,对于belongsTo的关系是dissociate(); 对于belongsToMany的关系是detach();

还有一些特定的绑定解除方法,我们再单独的关系模型中讲;

一对多

反绑

如果你要通过belongsTo关系绑定,可以用associate()来绑定,最后要save()一下,如图;

多对多

由于belongsTo换成了belongsToMany, 所以对应的绑定方法换成了attach()和detach();注意这里面填对象ID,可以用数组形式批量绑定;

save()方法仍然适用与关系绑定;

对中间表的操作

由于多对多关系多了一张中间表,Eloquent除了默认对这里面的外键进行操作以外,还可以对中间表的其他字段进行操作,看示例:

App\User::find(1)->roles()->save($role, ['expires' => $expires]);
登入後複製
$user->roles()->attach($roleId, ['expires' => $expires]);
登入後複製
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
登入後複製
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
登入後複製

sync()方法

sync就是同步,意思是说中间表会同步成sync()里面参数一样,没有写在参数里的都会移除,因此可以用来解除绑定;

Has Many Through(跨表一对多)

其实这只是一种快速查询方法,看图,本来可以先通过Conuntry查User,然后通过User查Post,现在你可以通过Country直接查Post;

通常Country和User,User和Post的表间关系都是事先建立好的,这个时候你再使用hasManyThrough;

Polymorphic Relations(belongsTo多态)

本来belongsTo只能属于一种对象的,就像女朋友只能属于男朋友;现在好了,女朋友不仅可以属于男朋友,还可以属于干爹了。

开玩笑的,最常见的应用还是图片,可以属于多种模型,看图;

我们发现这里的动词变成了morphTo(), morphMany();

先上一小段英语课,提升一下语感:

morph这个词的意思是改变形态,简称变态;这个和变形金刚的那个transform是不一样的,那个主要是改变形状;

morphTo(), morphMany(); 其实就是belongsTo() 和 hasMany() 多态形式,多态就是不仅拥有男票,还有干爹,有点“变态”;

关于绑定和解绑

associate()不适用用于morphTo();所以只能单向的用save()绑定了;

关于解绑,dissociate()也不适用用于morphTo();所以,只能把Photo实例删除!!删除了就没任何关系了(因为没有中间表)

感觉有点不是很自然的设计,不过目前调查下来情况就是这样;

Many To Many Polymorphic Relations(belongsToMany多态)

这个最典型的应用就是标签了,标签要涉及多对多的关系,还涉及对应不同类型的模型的问题,所以就是belongsToMany+多态;

看图,可绑定,可解绑;

Eager Loading(预加载)

这个问题很简单,看个实例你就懂了:

$books = App\Book::all();foreach ($books as $book) {    echo $book->author->name;}
登入後複製

万一books有一万本,那么循环就要1万次,每次循环,因为用了关联查询 $book->author->name; ,都会读数据库一次,意味着至少读数据库一万次,数据库哭了。

Eager Loading 就是让数据库读取发生在循环之前:

$books = App\Book::with('author')->get();foreach ($books as $book) {    echo $book->author->name;}
登入後複製

看,加了个神奇的with()后,所有数据在foreach前都读出来了,后面循环的只是读出来的数据,一共查询数据库2次!!

Eager Loading可以极大的缓解数据库查询压力,是性能优化的重要手段!

Eager Loading 多个关系

就是一次多加几张关联表而已;

$books = App\Book::with('author', 'publisher')->get();
登入後複製

嵌套 Eager Loading

$books = App\Book::with('author.contacts')->get();
登入後複製

把书的作者读出来,顺便把作者的联系方式读出来。

有条件的 Eager Loading

上面说的是整张表整张表的读出来,太土豪了,其实有时候我们只需要表里的部分记录:

$users = App\User::with(['posts' => function ($query) {    $query->where('title', 'like', '%first%');}])->get();
登入後複製

这中闭包的写法我们讲过多次,就是加个条件而已;

Lazy Eager Loading

这标题难道不是自相矛盾吗?又Lazy,又Eager?

哦,原来是在lazy的流程里判断需不需要eager loading一下:

$books = App\Book::all();if ($someCondition) {    $books->load('author', 'publisher');}
登入後複製
$books->load(['author' => function ($query) {    $query->orderBy('published_date', 'asc');}]);
登入後複製

注意这个load(),这是对collection用的;

跨模型更新时间戳

简单的来说,就是一条评论更新的时候,顺便把文章的'updated_at'字段也更新了;

namespace App;use Illuminate\Database\Eloquent\Model;class Comment extends Model{    /**     * All of the relationships to be touched.     *     * @var array     */    protected $touches = ['post'];    /**     * Get the post that the comment belongs to.     */    public function post()    {        return $this->belongsTo('App\Post');    }}
登入後複製

设置$touches这个属性;

然后你更新Comment的时候,就会把Post的'updated_at'字段也更新了;

更多内容请访问: Laravel 5.1 文档攻略

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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

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

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? 說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

See all articles