【Laravel8】DBクラスとクエリビルダとEloquentの違いについて


概要と当初の疑問

SQL歴10年以上、Laravel歴半年くらいです。
Laravel(に限らずWebフレームワーク全般)でSQLを操作するときに一番最初に思った疑問が
なんでSQL直接書かないの? でした。
個人的な所管を書いておこうと思います。

結論

データベースから取得したデータは結局PHPで処理するので
最初からPHPで扱いやすいようにクラスが用意されている。

DBクラス

  • DBクラスとはLaravelで用意されている最も手軽にDB操作するためのクラスである。
  • 以下の様にselect/update/deleteメソッドを使い、SQLをほぼそのまま書く。SELECTの戻り値はテーブルのカラム名が名前になった連想配列。

    $items = DB::select('select * from posts where id = :id', $param);
    DB::update('update posts set title = :title , body = :body where id = :id',$param );
    DB::delete('delete from posts where id = :id', $param);
    
  • DBクラスはSQLを直接書くため、1文字でも間違えているとエラーになったり、パラメータ結合だと実行してからでないとエラーが分からないなどバグが多くなるらしい。またセキュリティ的にもパラメータを直接埋め込むためSQLインジェクションの危険性も高い。

  • 開発的にはphp内にSQLという別の言語が混じるのもコーディングしずらいらしい。(私はSQL直の方が全然分かりやすかったですが、郷に入っては郷に従えということで…)

クエリビルダ

  • SQLクエリをphpチックに書くDBクラスの中のメソッドたち。
  • 以下の様にtableメソッドに様々なメソッドをチェーンして(つなげて)書く。
  • SELECTの戻り値はコレクションであり、Laravelの1つのクラスオブジェクトである。なのでメソッドをチェーンして書くことができる。

    $items = DB::table('posts') // ←SQLクエリをビルドしている
        ->where('title', 'like', '%' . $request->word . '%') // ←SQLクエリをビルドしている
        ->orwhere('body', 'like', '%' . $request->word . '%') // ←SQLクエリをビルドしている
        ->get(); // ←クエリをExecuteしている
    

Eloquent

  • DBクラスよりもっとphp内で使いやすくしたのがEloquentという。
  • ORMとはObject-Relational-mapppingの略で、DBとphpのクラスという異なる構造のデータをphp的にするための仕組みのこと。PythonとかRubyの各言語でも同様の仕組みがある。
  • LaravelのORMはEloquentというクラスを使用する。
  • Eloquentではモデルというクラスを使ってDBを操作する。
  • テーブル=モデルの関係であるため、phpのインスタンスを操作する感覚でテーブルを操作でき、SQLも作成できる。
  • こいつのなにがいいのかというと、例えばpost::all()などで返ってくる値は配列ではなくモデルクラスのインスタンスなので、クラスを拡張することで独自メソッドを追加することができる。
  • 固定で取得してくる項目などを独自メソッドとして定義しておけばそのメソッドを呼ぶだけで固定の複数項目を取得できる。いろんなところで同じロジックを書かなくてよくなるため再利用性が高まる。

これからも疑問に思ったことを自分の備忘録的に書いていこうと思います。