SQLクエリ実行
Laravelでデータベース処理を行うための大原則であるデータベース接続情報の設定について理解してもらえたところで、Laravelの3種類のデータベース処理を順番に紹介していきましょう。まずは、SQLクエリ実行です。
生のSQL実行
SQLクエリ実行の英語での正式名称は、「Running Raw SQL Queries」です。「Raw」とあることから分かるように、この方法は、ほぼ生のSQLを実行するものであり、ピュアPHPコードに近いです。例えば、fldbデータベース内にある部門情報を表すdeptsテーブルがあるとします。各カラムは、主キーのid、部門番号を表すdp_no、部門名を表すdp_name、部門の所在地を表すdp_loc、更新日時を表すupdated_at、作成日時を表すcreated_atから成り立っているとします。このテーブルから主キーidで検索するSELECT文を実行する場合、リスト2のようなコードをコントローラクラスのメソッド内に記述することになります。なお、ここではコントローラクラスとしてChap9Controllerクラスを想定しています。
public function showOneDeptByRaw()
{
$sql = "SELECT * FROM depts WHERE id = :id"; // (1)
$bindParams = [":id" => 1]; // (2)
$deptList = DB::select($sql, $bindParams); // (3)
foreach($deptList as $dept) { // (4)
print($dept->id.": ".$dept->dp_name."<br>"); // (5)
}
return "<p>処理終了</p>";
}
このリクエスト処理メソッドshowOneDeptByRaw()を実行すると、図1の画面が表示されます。
Laravelには、\Illuminate\Support\Facades\DBクラスというものが存在し、そのメソッドselect()を実行することで、生のSELECT文を実行できます。それがリスト2の(3)です。その際、第1引数としてSELECT文の文字列を渡します。リスト2では、あらかじめ(1)で文字列変数を用意し、渡しています。そのSELECT文中でプレースホルダによる変数のバインドを利用する場合は、バインドする変数を連想配列の形で用意し、それをselect()の第2引数として渡します。(3)の第2引数$bindParamsはバインド変数を表し、それをあらかじめ用意しているのが(2)です。
もし、バインド変数を利用しない場合は、第2引数を省略します。
戻り値は1行分のPHPオブジェクトが格納された連想配列
戻り値は、実行結果が格納された連想配列です。リスト2では、主キー検索によるSQL文であることから、実行結果は1件のみです。それでも連想配列として格納されるので注意してください。それをループしているのが(4)です。もちろん結果が1件ということを想定して、次のように記述してもかまいません。
$dept = $deptList[0];
上記$dept、あるいはリスト2のループ中の$deptは、実行結果表の1行分のデータが格納されたPHPオブジェクトです。このオブジェクトのプロパティは、データベースのカラムと一致するように自動的に作られます。そのため、リスト2の(5)のように、カラム名をプロパティ名としてアクセスしてデータを取り出すことが可能となります。
SQLクエリ実行メソッド
このように、生のSQLを実行する場合は、そのSQL文に合わせたメソッドがそれぞれ用意されています。表2に戻り値も含めてまとめておきます。
| メソッド名 | 対応するSQL文 | 戻り値 |
|---|---|---|
| select() | SELECT文 | 実行結果が格納された連想配列 |
| insert() | INSERT文 | なし |
| update() | UPDATE文 | UPDATEされた行数 |
| delete() | DELETE文 | DELETEされた行数 |
| statement() | DDL文などのDBからの応答を不要とするSQL文 | なし |
クエリビルダ
Laravelによるデータベース処理の2個目は、クエリビルダです。クエリビルダは、簡単にいうと、LaravelのメソッドをつなげていくことでSQL文の代わりになるものです。
クエリビルダの基本はテーブル指定
クエリビルダを利用する場合は、DBクラスのtable()メソッドを実行することから始まります。その際、引数としてSQL実行対象のテーブル名を記述します。
例えば、リスト3のような記述です。
public function showAllDeptsByBuilder()
{
$deptList = DB::table("depts")->get(); // (1)
foreach($deptList as $dept) {
print($dept->id.": ".$dept->dp_name."<br>");
}
return "<p>処理終了</p>";
}
このリクエスト処理メソッドshowAllDeptsByBuilder()を実行すると、図2の画面が表示されます。
リスト3の(1)にあるように、table()メソッドの引数としてdeptsテーブルを指定し、続けて、処理するSQLに応じてメソッドをつなげることで、そのテーブルへのSQL文を自動生成し、実行してくれます。これがLaravelのクエリビルダです。
リスト3ではget()メソッドを実行しています。これは、全データを取得するメソッドであり、戻り値である$deptListは、全データが格納された連想配列となっています。各要素は、SQLクエリ実行のselect()メソッドの戻り値と同様に、実行結果表の1行分のデータが格納されたPHPオブジェクトですので、プロパティ名でカラムデータにアクセスできます。
クエリビルダの絞り込みメソッド
クエリビルダでSELECT文を実行するためのメソッドは、そのパターンに応じてさまざまなものが用意されています。詳細はこちらの公式マニュアルを参照してください。ここでは、主なものをいくつか紹介します。
まず、WHERE句による絞り込みを行いたい場合は、where()メソッドとget()メソッドを併用します。例えば、次のようなコードです。
$deptList = DB::table("depts")->where("dp_loc", "LIKE", "%大阪%")->get();
第1引数にカラム名、第2引数に比較するための演算子記号、第3引数に値を記述します。
get()での戻り値は、たとえ絞り込まれていたとしても連想配列となります。これを、最初の1行だけ取得したい場合、次のようにfirst()メソッドを利用します。
$dept = DB::table("depts")->where("dp_no", "=", 10)->first();
この場合の戻り値は、連想配列ではなく、1行分が格納されたPHPオブジェクトそのものとなります。SQLの実行結果表があらかじめ1行と分かっている場合は、get()ではなくfirst()を利用した方がスッキリします。
さらに、主キーidでの検索となると、次のようにfind()メソッドが利用できます。引数は主キーの値を渡します。
$dept = DB::table("depts")->find(2);
この場合も、結果表は1行ですので、戻り値は連想配列ではなく、PHPオブジェクトとなります。
INSERTのクエリビルダ
クエリビルダを利用してINSERTを実行する場合は、同名のメソッドを利用します。その際、引数として挿入データを記述した連想配列を渡します。例えば、次のようなコードです。
DB::table("depts")->insert(["dp_no"=>50, "dp_name"=>"バレー部"]);
戻り値はありません。
もし、主キーidカラムがAUTO_INCREMENTの場合は、insert()メソッドの代わりにinsertGetId()メソッドを利用することで、挿入行に対する主キー値を戻り値として取得することができます。
UPDATE/DELETEのクエリビルダ
クエリビルダを利用してUPDATE文とDELETE文を実行する場合は、where()メソッドに続けて同名のメソッドを記述します。
UPDATEの場合は、例えば次のようなコードになります。update()メソッドの引数として更新データの連想配列を渡します。
$result = DB::table("depts")->where("id", 4)->update(["dp_loc", "姫路"]);
この場合、idが4の行のdp_locカラムの値を「姫路」に更新します。戻り値は、UPDATEされた行数を表します。
DELETEの場合は、delete()メソッドの引数は不要で、次のようなコードとなります。
$result = DB::table("depts")->where("dp_name", "会計")->delete();
戻り値はDELETEされた行数です。
