Laravel – クエリービルダー

準備

以下の3つのテーブルを使ってクエリービルダーの動作を確認する。

3つのテーブルを結合させるSQLの例。

SQLの実行結果。

基本操作

tinkerで確認する。

ビルダーの書き方

DBファサードのtableメソッド

DBファサードのtable()メソッドを使う場合。

モデルのビルダーメソッド

モデルのビルダーメソッドを直接実行する場合。

ビルダーのインスタンスを保存して使う

DBファサードのtable()メソッドの場合、tinkerだと以下のように詳細な内容が表示される。toSql()メソッドで構築されるSQLが確認できる。

モデルからビルダーメソッドを直接呼び出す場合、tinkerでのインスタンスは表示はシンプルになる。

SQLや実行結果などの取得・確認方法

ビルダーのインスタンス取得

クエリービルダーを実行すると、ビルダーのインスタンスが得られる。

get()~実行結果の取得

クエリービルダーの実行結果はget()メソッドで得る。

toSql()~SQLの確認

toSql()メソッドでビルダーで生成されるSQLを確認できる。

getBindings()~バインドされる値の確認

バインドされる値はgetBindings()メソッドで確認できる。

クエリービルダーメソッドのチェーン

複数のコマンドを含むSQLの場合は、コマンドに対応するクエリービルダーメソッドをチェーンで繋げる。

メソッドチェーンの順番は問わない。以下のようにメソッドの順番を変えても、生成されるSQLは同じ。

コントローラーでの記述

基本の書き方

以下のルーティングで基本の書き方を確認。

コントローラーでの書き方。DBファサードを使う例。

  • customersテーブルのnameカラムの値を取得している
  • 結果は配列customersで各要素は2つの要素idnameを持つ連想配列となる
  • $customersをビューに渡している

ビューでは受け取った$customersの各要素を取り出し、idとnameを表示。

なおdd()で表示させた$customersの内容は以下のとおり。

メソッドチェーン

SQLの行が増えてきた場合、メソッドチェーンでビルダーメソッドを繋げる。

まず以下のようなルーティングを定義。

コントローラーのアクション内でメソッドチェーンを記述。以下の例では、冒頭のLEFT JOINを使ったSQLを意図している。

なお本筋ではないが、select()メソッドの要素内でASによるエイリアスを定義できる。

メソッドチェーンでSQLをビルドした場合、結果は指定したカラムを持つ複数レコードが2次元配列で返される。

以下はビューで受け取った$ordersを表示させる例。foreachで1レコードに相当する連想配列を取り出し、ネストしたforeachで各レコードの属性・内容の対を取り出して表示させている。

ブラウザーには以下の様に表示される。

  1. ordered_at: 2020-06-05 00:00:00
  2. customer_name: customer1
  3. address: customer1@mail.com
  4. item: screw
  1. ordered_at: 2020-06-05 00:00:00
  2. customer_name: customer2
  3. address: customer2@mail.com
  4. item: rubber sheet
  1. ordered_at: 2020-06-06 00:00:00
  2. customer_name: customer2
  3. address: customer2@mail.com
  4. item: plastic plate
  1. ordered_at: 2020-06-07 00:00:00
  2. customer_name: customer1
  3. address: customer1@mail.com
  4. item: rubber sheet
  1. ordered_at: 2020-06-08 00:00:00
  2. customer_name: customer3
  3. address:
  4. item: wire

モデルのリレーション設定に基づく場合

クエリービルダーのメソッドチェーンへの対比として、同じデータをモデル間のリレーション定義に基づいて操作する例を示す。

CustomerEmailOrderの各モデルにリレーションに関する記述を追加する。

コントローラーではOrderモデルの全データを取り込み、ビューに渡す。

ビューでは受け取った$ordersから要素を順に取り出して、関連付けられたデータを表示させる。関連付けられたデータがない場合のエラーを防ぐため、optional()ヘルパーを使っている

ブラウザーには以下の様に出力される。emailが存在しない場合は無表示となっている。

  1. 2020-06-05 00:00:00: customer1
    • e-mail: customer1@mail.com
    • item: screw
  2. 2020-06-05 00:00:00: customer2
    • e-mail: customer2@mail.com
    • item: rubber sheet
  3. 2020-06-06 00:00:00: customer2
    • e-mail: customer2@mail.com
    • item: plastic plate
  4. 2020-06-07 00:00:00: customer1
    • e-mail: customer1@mail.com
    • item: rubber sheet
  5. 2020-06-08 00:00:00: customer3
    • e-mail:
    • item: wire

なおdd()で表示させた$ordersの内容は以下のとおり。1つ目の要素のみ展開している。

クエリービルダーとリレーション

クエリービルダーでSQLを発行すると、フレームワークに負担をかけずにDBMS側でデータを絞り込めるが、その方法によっては意図した動作にならなかったり、リレーションを使えない場合がある。

結論としてはモデルクラスでクエリービルダーを記述するのがよさそうだが、その詳細についてはこちらにまとめた。

クエリービルダーでのエイリアス

クエリービルダーでSQLと同様にエイリアスを定義できる。クエリービルダーでのエイリアスを参照。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です