ホームページ >バックエンド開発 >PHPチュートリアル >PHP の Laravel フレームワークでの Eloquent オブジェクト リレーショナル マッピングの使用について

PHP の Laravel フレームワークでの Eloquent オブジェクト リレーショナル マッピングの使用について

不言
不言オリジナル
2018-06-13 14:13:342018ブラウズ

この記事では主に、PHP の Laravel フレームワークにおける Eloquent のオブジェクト リレーショナル マッピングの使用法を紹介し、必要な友人が参照できる Eloquent のデータ モデル間の関係に焦点を当てます。

ゼロ、Eloquent とは何ですか。
Eloquent は Laravel の「ORM」、つまり「Object Relational Mapping」、つまりオブジェクト リレーショナル マッピングです。 ORM の登場は、データベース操作をより便利にするために役立ちます。

Eloquent では、「モデル クラス」をデータベース テーブルに対応させることができ、最下層に多くの「関数」をカプセル化しているため、モデル クラスの呼び出しが非常に便利です。
次のコードを見てください:

<?php

class Article extends \Eloquent {

protected $fillable = [];

}

'protected $fillable = [];' このコード行には値はなく、によって自動的に生成されます。ジェネレーターについてはここでは説明しません。

このクラスには、指定された名前空間もコンストラクターもありません。無意味なコード行が含まれていない場合、このファイルには 'Article ' と '\Eloquent' という 2 つの意味があるだけになります。そうです、Eloquent はとても素晴らしいのです。Eloquent クラスを継承するだけで、「first() find() where() orderBy()」など、非常に多くのことが実行できます。これが object- の強力な機能です。指向性のある。

1. Eloquent の基本的な使用法

早速、Eloquent のいくつかの一般的な使用法のコードを直接示します。

ID 2 の記事を検索し、そのタイトルを印刷します。

$article = Article::find(2);

echo $article->title;

「I am the 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 で ID を検索します ~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 を継承するすべてのクラスには 2 つの「固定使用法」「Article::find($number)」があります。記事::all()'、前者はデータベースから取り出した値を持つオブジェクトを取得し、後者はデータベース全体を含むオブジェクトのコレクションを取得します。

2. 「where()」「orderBy()」などのすべての中間メソッドは、「静的」呼び出しメソッドと「非静的連鎖」呼び出しメソッド、つまり「Article::where」の両方をサポートできます。 ( )...」および「Article::....->where()」。

3. すべての「非固定使用法」呼び出しには、「終了」するための操作が必要です。「->get()」と「->first()」という 2 つの「終了操作」があります。 )」。

2. 中間操作の流れ
ビルダーという言葉は直訳するとコンストラクターとなりますが、データベース操作は主に一連の操作であるため、「中間操作の流れ」という方が理解しやすいと思います。 。

中間操作フロー。コードを参照してください:

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()` は中間の操作フローです。中間の操作フローはオブジェクト指向のアプローチを使用して理解され、次の 1 つの文に要約できます。

オブジェクトを作成し、そのプロパティを継続的に変更し、最後に操作を使用してデータベース操作をトリガーします。

中間操作フローに関する手がかりを見つける方法

文書には中間操作フローに関する貴重な情報がほとんどありません。では、どうやってこれを見つければよいのでしょうか。非常に簡単です。次のコードを使用します:

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

すると、次のエラーが表示されます:


2016226161019074.jpg (929×97)

エラーが発生するのはなぜですか?なぜなら、`Article::where()` はまだ `Article` オブジェクトではなく `Builder` オブジェクトであるため、`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);

3. モデル間の関係 (関連付け)1. 名前としては 1 対 1 の関係です。これは、2 つのモデル間に 1 対 1 の関係があることを示しています。この種のリレーションシップには中間テーブルは必要ありません。
User と Account の 2 つのモデルがあり、それぞれ登録ユーザーと消費者に対応するとします。次に、 によって提供される 1 対 1 の関係メソッドを使用したいとします。雄弁に、テーブル構造は次のようになります:

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。