목차
简介
基本概念
一对一
要点:反复观察图!
定义模型
定义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 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) 11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) Mar 03, 2025 am 10:49 AM

종종 키워드와 추적 매개 변수로 혼란스러워하는 긴 URL은 방문자를 방해 할 수 있습니다. URL 단축 스크립트는 솔루션을 제공하여 소셜 미디어 및 기타 플랫폼에 이상적인 간결한 링크를 만듭니다. 이 스크립트는 개별 웹 사이트 a에 유용합니다

Laravel의 플래시 세션 데이터로 작업합니다 Laravel의 플래시 세션 데이터로 작업합니다 Mar 12, 2025 pm 05:08 PM

Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

Laravel Back End : Part 2, React가있는 React 앱 구축 Laravel Back End : Part 2, React가있는 React 앱 구축 Mar 04, 2025 am 09:33 AM

이것은 Laravel 백엔드가있는 React Application을 구축하는 데있어 시리즈의 두 번째이자 마지막 부분입니다. 이 시리즈의 첫 번째 부분에서는 기본 제품 목록 응용 프로그램을 위해 Laravel을 사용하여 편안한 API를 만들었습니다. 이 튜토리얼에서는 Dev가 될 것입니다

Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Mar 12, 2025 pm 05:09 PM

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> ​​'Hello World', 'github.com'=> ​​[ 'foo'=> 'bar'], 'forge.laravel.com'=>

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 Mar 14, 2025 am 11:42 AM

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Mar 13, 2025 pm 12:08 PM

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

2025 PHP 상황 조사 발표 2025 PHP 상황 조사 발표 Mar 03, 2025 pm 04:20 PM

2025 PHP Landscape Survey는 현재 PHP 개발 동향을 조사합니다. 개발자와 비즈니스에 대한 통찰력을 제공하는 프레임 워크 사용, 배포 방법 및 과제를 탐색합니다. 이 조사는 현대 PHP Versio의 성장을 예상합니다

라 라벨에서 알림 라 라벨에서 알림 Mar 04, 2025 am 09:22 AM

이 기사에서는 Laravel 웹 프레임 워크에서 알림 시스템을 탐색 할 것입니다. Laravel의 알림 시스템을 사용하면 다른 채널을 통해 사용자에게 알림을 보낼 수 있습니다. 오늘은 알림을 보낼 수있는 방법에 대해 논의합니다

See all articles