ホームページ >バックエンド開発 >PHPチュートリアル >Laravel 5.1 ドキュメント戦略 -- Laravel Eloquent ORM の最も強力だが理解が難しい部分: データ関係
実際、Eloquent ORM はテーブル操作をデータ モデル操作に置き換えることができることを誰もが知っています。そのため、テーブルの関連クエリは Eloquent にあります。これは、モデル間の関連付けクエリです。これがこの章の主要な内容です。
Eloquent は、次の 6 種類のテーブル間リレーションシップをサポートします。
One To One (1 対 1) )
1 対多
多対多
Has Many Through (テーブル間で 1 対多)
多態性関係 (belongsTo 多態性)
多対多多態性関係 (belongsToMany 多態性) )
最初の 3 つの関係が何であるかについては説明しません (Baid 自身で理解してください) これには、多くの忍耐とオブジェクト思考に慣れる努力が必要です。とりあえずは SQL ですが、しばらく練習すればとても簡単に使えることがわかります。
もちろん、Eloquent は強力すぎるため、毎回多くのものがロードされると不満を言う人もいます。これは効率に影響します (実際には影響はありませんので、納得できない場合は取得してください。データが教えてくれました) が、コード作成効率、可読性、保守性の点で質的な飛躍であると言えるので、それを優先することを強くお勧めします。
私はこの章を最初に学びましたが、チュートリアルを書いたのは最後でした。幸いなことに、私は製品の出身なので、複雑なことを明確に説明できるはずです。地球上で最も強力な ORM を理解しましょう: Eloquent
まずその使用方法を見てみましょう:
$user->posts()->where('active', 1)->get();
使用方法は次のとおりです。 $user オブジェクトは、彼が合計で公開した記事の数を調べます (ステータスは公開済み)。
ここでは、posts() が $user のメソッドであることがわかります。そのため、関連するクエリを使用するには、まず $user モデルで関係 (メソッド) を定義する必要があります。 -one
この図から、Eloquent モデル リレーションシップを使用するには、最初のステップでモデル内でモデル リレーションシップを定義し、2 番目のステップで正しいモデル リレーションシップを準備することがわかります。 3 番目の部分では、クエリ メソッドのバインディングとアンバインド メソッドを使用します。このプロセスに従って、次のモデルの関係を理解して説明します。絵を繰り返し観察してください!
モデルの定義
namespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{ public function phone() { return $this->hasOne('App\Phone'); }}注: モデルを定義するときは、単数形に注意してください混乱を避けるために、メソッド名には単数形を使用し、「1 つ」には単数形を使用し、「多数」には複数形を使用します。 hasOne() などのリレーションシップ バインディング メソッドは数多くありますが、徐々に慣れて、使用中に注意する必要があります。
namespace App;use Illuminate\Database\Eloquent\Model;class Phone extends Model{ public function user() { return $this->belongsTo('App\User'); }}
主に注意すべき点は、この例には外部キーと中間テーブルが含まれていないことです。
モデル リレーションシップ メソッド。クエリ
$user->posts()->where('active', 1)->get();リレーションシップを属性として使用して、コレクションを直接検索できますが、欠点は、DQB メソッドを続行できないことです。
これら 2 つのメソッドは非常に一般的に使用されるため、適切に使用する必要があります (以下同様、説明は省略します)
$user->posts;
共通のバインディングメソッドは save( ; リレーションシップ モデル内;
1 対多
バック バインディング
belongsTo 関係を通じてバインドする場合図に示すように、associate() を使用して Determine をバインドし、最後に save() を実行できます。
多対多
オブジェクト ID がここに入力され、配列形式でバッチでバインドできることに注意してください。
中間テーブルの操作
sync() メソッド
sync は同期です。中間テーブルは sync() で同じパラメータに同期され、パラメータに書き込まれていないパラメータは移動されるため、
Has Many Through (クロステーブル 1) に使用できます。 -to-many)
実際には、これは単なる簡単なクエリ方法です。図を見てください。本来は、まず国からユーザーを確認し、次にユーザーから今すぐ投稿を確認することができます。 Country を介して Post を直接確認できます。
App\User::find(1)->roles()->save($role, ['expires' => $expires]);
$user->roles()->attach($roleId, ['expires' => $expires]);通常、 Country と User、User と Post テーブルの間の関係は事前に確立されています。このとき、hasManyThrough;
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
$user->roles()->sync([1 => ['expires' => true], 2, 3]);多態性関係 (ポリモーフィズムに属します)
本来belongsTo只能属于一种对象的,就像女朋友只能属于男朋友;现在好了,女朋友不仅可以属于男朋友,还可以属于干爹了。
开玩笑的,最常见的应用还是图片,可以属于多种模型,看图;
我们发现这里的动词变成了morphTo(), morphMany();
先上一小段英语课,提升一下语感:
morph这个词的意思是改变形态,简称变态;这个和变形金刚的那个transform是不一样的,那个主要是改变形状;
morphTo(), morphMany(); 其实就是belongsTo() 和 hasMany() 多态形式,多态就是不仅拥有男票,还有干爹,有点“变态”;
associate()不适用用于morphTo();所以只能单向的用save()绑定了;
感觉有点不是很自然的设计,不过目前调查下来情况就是这样;
这个最典型的应用就是标签了,标签要涉及多对多的关系,还涉及对应不同类型的模型的问题,所以就是belongsToMany+多态;
看图,可绑定,可解绑;
这个问题很简单,看个实例你就懂了:
$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次!!
就是一次多加几张关联表而已;
$books = App\Book::with('author', 'publisher')->get();
$books = App\Book::with('author.contacts')->get();
把书的作者读出来,顺便把作者的联系方式读出来。
上面说的是整张表整张表的读出来,太土豪了,其实有时候我们只需要表里的部分记录:
$users = App\User::with(['posts' => function ($query) { $query->where('title', 'like', '%first%');}])->get();
这中闭包的写法我们讲过多次,就是加个条件而已;
这标题难道不是自相矛盾吗?又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 文档攻略