Eloquent
Laravelによるデータベース処理の最後に紹介するのは、Eloquentです。
Eloquentとは
これまで紹介してきたSQLクエリ実行にしても、クエリビルダにしても、SELECT文を実行した結果というのは、その結果表の1行分のデータを丸々格納できるようにしたPHPオブジェクトでした。それと同じように、ひとつのテーブルの1行分のデータに対応したクラスをあらかじめ作成し、そのクラスとテーブルデータとを自動で結びつける機能がここで紹介するEloquentです。そして、テーブルと1対1で対応するように作成されたクラスのことを、モデルクラスといいます。
モデルクラスの作成
実際にモデルクラスを作成してみましょう。このようなモデルクラスは、デーブルごとに用意することになっていますので、どこかひとつのディレクトリにまとめておいた方が良いです。そこで、appフォルダ直下にModelsというディレクトリを作成し、そこにdeptsテーブルに対応するモデルクラスとしてDeptクラスを作ってみましょう。これは次のようなコードとなります。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Dept extends Model // (1)
{
}
目を疑うようなコードです。クラス内の記述は何もありません。それでも、これで問題なく動作します。というのも、(1)にあるように、モデルクラスは\Illuminate\Database\Eloquent\Modelクラスを継承して作成すれば、それだけでモデルクラスとして機能するからです。その際、クラス名をテーブル名の単数型のキャメル記法で記述するのが約束ごとになっています。裏を返せば、テーブル名は複数形である必要があります。もしこの対応関係が成り立たないテーブル設計の場合は、モデルクラス内に$tableプロパティでテーブル名を指定する必要があります。例えば、次のようなコードです。
class Customer extends Model
{
protected $table = "kokyaku";
}
テーブルの主キーについても同様で、主キーのカラム名がidの場合は、モデルは自動的に主キーとして扱ってくれます。それ以外のカラム名を主キーとした場合は、$primaryKeyプロパティに記述します。例えば、次のようなコードです。
class Order extends Model
{
protected $table = "jyuchu";
protected $primaryKey = "jyuchu_id";
}
このように、さまざまなテーブル設計パターンにも対応できるようにモデルは作られていますが、可能ならばテーブル設計の段階から、テーブル名は英単語の複数形に、主キーはidでAUTO_INCREMENTにしておく方が、モデルクラスをすんなり使えるようになります。
データ取得はモデルクラスのメソッドを利用
このようにして作成したモデルクラスを利用してデータを取得する場合は、そのモデルクラスに用意されているメソッドを利用します。例えば、全データの取得はall()メソッドを利用し、リスト5のようなコードとなります。
public function showAllDeptsByModel()
{
$deptList = Dept::all(); // (1)
foreach($deptList as $dept) {
print($dept->id.": ".$dept->dp_name."<br>");
}
return "<p>処理終了</p>";
}
リスト5では(1)でDeptクラスのall()メソッドを実行し、結果が格納された連想配列を取得しています。各要素は、Deptクラスそのものです。そして、このDeptというモデルクラスには、自動的にカラム名に対応したプロパティが用意されています。そのため、SQLクエリ実行やクエリビルダの戻り値と同様に、カラム名のプロパティでアクセスできます。
データの絞り込みなどはクエリビルダと同じ
Eloquentは、実は内部でクエリビルダと同じことを行っています。そのため、モデルクラスに対して、クエリビルダと同じメソッドが利用できます。例えば、WHERE句による絞り込みは、次のようなコードとなります。
$deptList = Dept::where("dp_loc", "LIKE", "%大阪%")->get();
where()メソッドを実行する対象がDB::table()メソッドの戻り値からモデルクラスであるDeptに変わったこと以外は、何ら変わりありません。もちろん、first()メソッドやfind()メソッドも利用できます。
INSERTの実行
一方、INSERT/UPDATE/DELETEといった更新系処理は、クエリビルダとは異なります。INSERTの場合は、次のようなコードとなります。
public function insertDeptByModel()
{
$dept = new Dept(); // (1)
$dept->dp_no = 90; // (2)
$dept->dp_name = "バレー部"; // (2)
$dept->save(); // (3)
return "<p>処理終了</p>";
}
リスト6の(1)のように、モデルクラスをnewして、インスタンスを生成します。そのインスタンスのプロパティに対して、(2)のように必要データを格納します。このようにして、データ格納されたモデルインスタンスのsave()メソッドを実行するだけでINSERT処理が行われます。それが(3)です。
UPDATEとDELETEの実行
UPDATEとDELETEについては、まず対象データを取得することから始めます。例えば、UPDATEは、次のようなコードです。
$dept = Dept::find(5); $dept->dp_loc = "姫路"; $dept->save();
find()で取得してきたインスタンスに対して、プロパティのデータを書き換え、save()メソッドを実行します。
一方、DELETEの場合は、このsave()の代わりに、次のように、delete()メソッドを実行するだけです。もちろんプロパティへのデータ格納は不要です。
$dept = Dept::find(5); $dept->delete();
結局どれを使えばいいのか
ここまで、Laravelの3種のデータベース処理を紹介してきました。すると、「結局どれを使えばいいのか」という疑問が湧いてくると思います。これは、3種類それぞれに一長一短があるので、ケースバイケースとしか答えようがありません。
しかし、ある程度の指針はあります。まず、SQLクエリ実行は、ほぼ生のSQLが実行できるため、ゴリゴリSQLを記述して、ほとんどのデータ処理をSQLで行いたい場合に向いています。
一方、簡単なデータ処理の場合は、簡単なSQL文となるため、生のSQL文を記述する必要がないクエリビルダの方がお手軽といえます。
ただし、この両方とも戻り値がLaravelによって自動生成されたPHPオブジェクトになるため、データが格納されたプロパティを加工した上で値を取得するメソッドの記述ができません。そういった場合はEloquentを利用すると、モデルクラスとしてテーブルに対応したクラスが用意されるため、プロパティデータの加工メソッドが記述できます。また、各々のクラスがデータベース内のテーブルと1対1で対応するため、テーブルとの対応関係が把握しやすいです。
これらの特徴を理解した上で、どれかひとつというのではなく、使い分けていくのをお勧めします。
まとめ
今回は、Laravelのデータベース処理を紹介しました。
次回は、いよいよ最終回です。Laravelの認証機能を紹介します。
