【 Laravel 】クエリビルダ と Eloquent ORM の違いを整理！

#はじめに

Laravel でデータベースを操作するには、

__・DBクラス
・DBクラスのクエリビルダ 
・Modelクラスの Eloquent ORM__

上記３つのうち、どれかを使用しますが、

__学習中、クエリビルダ と Eloquent ORM の違いがよく分からないままに
使用してしまっていたので自分なりに整理しました！__

# 表でざっくり比較
|  |　　 　クエリビルダ　  　　|　　 　　Eloquent ORM　　 　　|
|:-:|:-:|:-:|
| __Modelが必要　__ |  × | ○ |
| __リレーション定義　__ | × | ○ |
| __タイムスタンプ更新　__ | × | ○ |
| __クエリビルダが使用可能　__ | ○ | ○ |
| __SQLインジェクション対策　__|  ○※  | ○※ |
| __記述量__ | __多め__ | __少なめ__ |

__※ クエリビルダ も Eloquent ORM も、SQL文を書くことができる Raw メソッドを使用する
場合は、コードを記述する者がSQLインジェクション対策を考慮したクエリを書く必要があるため注意が必要です。__

###Eloquent でもクエリビルダが使用できる。
> Tip!! Eloquentモデルはクエリビルダですから、クエリビルダで使用できる全メソッドを確認しておくべきでしょう。
  Eloquentクエリでどんなメソッドも使用できます。
[readouble.com Laravel 6.x Eloquent：利用の開始](https://readouble.com/laravel/6.x/ja/eloquent.html?header=%25E3%2582%25B0%25E3%2583%25AD%25E3%2583%25BC%25E3%2583%2590%25E3%2583%25AB%25E3%2582%25B9%25E3%2582%25B3%25E3%2583%25BC%25E3%2583%2597%25E3%2581%25AE%25E8%25A8%2598%25E8%25BF%25B0)

私の場合、これを失念したまま使用していたため、見た目が同じでなにが違うのか分からくなっていました。

###どちらもSQLインジェクション対策がされている。
>LaravelクエリビルダはアプリケーションをSQLインジェクション攻撃から守るために、
PDOパラメーターによるバインディングを使用します。バインドする文字列をクリーンにしてから渡す必要はありません。
[readouble.com Laravel 6.x Laravel 6.x データベース：クエリビルダ](https://readouble.com/laravel/6.x/ja/queries.html?header=%25E3%2582%25A4%25E3%2583%25B3%25E3%2583%2588%25E3%2583%25AD%25E3%2583%2580%25E3%2582%25AF%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%25B3)

__SQLインジェクションとは、悪意のあるユーザーが不正なクエリ( データベースへの命令文 )
を書き、データベースへアクセスしてデータの漏洩・改ざんを行う攻撃のこと。__

クエリビルダ を使用すれば、バインディングにより不正なクエリを、

``命令文ではなく "文字列" ``として扱ってくれるため、

安全なデータベースとのやり取りが可能になります。

___参考：___ [SQLインジェクション対策について - 独立行政法人 情報処理推進機構（ＩＰＡ）](https://www.ipa.go.jp/files/000024396.pdf)


# 所属するクラス

###・ クエリビルダ

``` 
Illuminate\Support\Facades\DB
```
###・ Eloquent ORM

```
Illuminate\Database\Eloquent\Model
```

#クエリビルダとは
　
__・SQL文をPHPのメソッドを使う感覚で、簡単に組み立てられるようにしたもの。
・SQL文を生成するためのメソッドを、メソッドチェーンで記述して、データベースを
　　操作することができます。__

記述は以下のようなイメージ

```
$article = DB::table('articles')
              ->join('users', 'articles.user_id', '=', 'users.id')
              ->select('articles.id as article_id', 'title', 'body', 'user_id','users.id', 'users.name')
              ->orderBy('articles.created_at', 'desc')
              ->get();
```
###メリット

__・PHPらしい記述方法ながらも、SQLライクに書けるから、どんなクエリが
　発行されているのかわかりやすい。
　
・そのため SQL 構文の知識がある人は使いやすい。
　
・join句を使ってクエリを書けば Eloquent でサブクエリを使うより速い。
　
・バインディング変数使用で、SQLインジェクション対策がされている。
　( Eloquent と 同様 )__
###デメリット

__・リレーションを正しく把握して、自分でテーブル結合をしなくてはならない。
　
・そのため SQL文の理解が必要。
　
・上記２点を正しく考慮できていないと、意図しないデータの取得や、データベースの
　　操作につながる恐れがある。
　　
・記述量が多くなりがち。__
#Eloquent ORM とは
####__Eloquent__ は Laravel で提供されている データベース操作のための機能で ___ORM の一種___ です。
### ORM とは
__Object-Relational Mapping の略__で、アプリケーションのModelと、データベースのテーブルを
マッピングする機能のことをいいます。( O/Rマッパーという呼ばれ方もしている )
### マッピングとは
オブジェクトとリレーショナルデータベースのレコードを対応付けることをいいます。
__テーブルをクラス、レコードをインスタンスとし、オブジェクトとして直感的に扱えるようにします。__
　
　
``データベースから " 取得したレコードは PHPのオブジェクトに変換　" ``
　
``データベースに　 " 渡す値はオブジェクトから レコードに変換 "``
###メリット
__・アプリケーション( Laravel )の中に別言語であるSQLを混在させずに済む。
・テーブル同士の関係性を定義できる。
　
・データベースのテーブルとレコードをPHPのクラスとインスタンスのように直感的に
　　扱うことができる。
　
・バインド変数を利用して 安全な SQL を作ってくれる。→ SQL インジェクション対策
　
・クエリビルダ のすべてのメソッドを使うことができる。__

　
__　SQL を書かないことにより、アプリケーションとデータベースが疎結合になり、
　データベースが何であろうと、アプリケーション側の実装に影響が出ない。__
　( データベースごとの方言を吸収してくれる。 )
　
　

###デメリット
__・初学者の場合、SQLが書けなくてもデータ取得ができるため、SQLの扱いに慣れない。
　
・見た目にどのようなクエリが発行されているか分からない。
　
・複雑な条件でデータを取得しようとすると記述が大変。
　
・メモリの消費が大きい。__

#どっちがいいの？

現役エンジニアさんに聞いてみたところ、
　
__「 どちらも一長一短があることと、現場によっても左右されるため、どちらがいいということはない 」__

という感じのお話。

調べてみれば、おっしゃるようにそれぞれのメリット・デメリットがわかりましたので、
　
どちらにも対応 + 生SQL の記述もできるように、学習を続けていこうと思った
クエリビルダ と Eloquent についての調べでした。

以上です。

__ここまでご覧いただきまして感謝いたします。ありがとうございます！__