株式会社WOWNエンジニアチームです。
前回、SQLクエリを実際に作成する手順の話をしました。
「SQL言語をそのまま書くのは面倒で難しい」「SQL言語を簡単に書く機能がある」という話です。
具体的には、以下のようなSQL言語があるとして、
SELECT users.name, users,email, COUNT(orders.id) AS order_count
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE users.age > 18
GROUP BY users.id
HAVING COUNT(orders.id) > 0
ORDER BY order_count DESC;
この内容を「Eloquent」という機能を活用して書くと、以下のようになります。
User::withCount(['orders' => function($query) {
$query->whereHave('count', '>', 0);
}])
->where('age', '>', 18)
->having('orders_count', '>', 0)
->orderBy('orders_count', 'desc')
->get(['name', 'email', 'orders_count']);
内容が記号などで区切られて、コードの量も減り、見やすくなりました。実に良いこと尽くめです。
Eloquentはなぜ同じ内容を短く書けるのか?それは扱うデータを「オブジェクト」という単位でまとめているからです。なのでEloquentの書き方の意味を知るには「オブジェクト指向」というプログラミングの考え方に触れる必要があります。
今回はそのオブジェクト指向の、ほんとうに初歩の一端の話をします。
そもそも、このEloquentを扱うLaravel(PHP)そのものがオブジェクト指向言語のプログラムではありますが、今は置いておきましょう。今回は難しい部分を抜きにして、データベースに触れるために必要な最低限のオブジェクト指向の話をします。
オブジェクト指向の3つの用語
オブジェクト指向の解説をするためには、「オブジェクト」「クラス」「パラメータ」という3つの用語について知る必要があります。
「パラメータ」
例えばSNSでユーザー登録する時、どんな項目を入力するでしょうか?
・名前
・メールアドレス
・パスワード
・年齢(生年月日)
などの項目を入力することでしょう。また、
・データベースに登録した時の通し番号(ID)
・登録した日付(タイムスタンプ)
といった項目はプログラム上で自動で追加され、すべての情報が揃ったところでユーザー登録が完了します。
データベースでは、こうして揃えた情報をまとめて「ユーザー」として登録します。
そして、こうしたユーザーが持っているひとつひとつの情報を「パラメータ(情報)」と呼びます。
ユーザーは名前というパラメータを持っていますし、メールアドレスというパラメータを持っています。
なのでSQLが「通し番号が3番のユーザーさん、あなたの名前は何ですか?」「2024/02/14以降に登録したユーザーはいませんか?」と尋ねることができます。
逆に言えば、ユーザーという単位は注文番号や商品名というパラメータを持っていません。
「通し番号が5番のユーザーさん、あなたの注文番号は何番ですか?」「メールアドレスがwown@example.comのユーザーさん、あなたの商品名は何ですか?」と尋ねられてもSQLには意味が分からないのです。もちろん、私たちにも意味が分かりません。
「クラス」
オブジェクト指向の教科書では、よく「金型」や「設計図」と呼ばれるものが「クラス」です
パラメータに関して、さきほどのような意味不明な質問をSQLにさせないためには、「ユーザーはどんなパラメータを持つことができるのか?」という取り決めをプログラムが知る必要があります。これが「クラス」の役割です。
ユーザーは名前というパラメータを持っている。メールアドレスというパラメータを持っている。注文番号を持っているわけではない、etc…
…などのデータの構造をあらかじめ決めておいて、ユーザーを登録する時にはこのクラスの構造に沿って登録をすれば、必要な情報が揃っており、不要な情報がないことが保証されるという寸法です。
また、逆に言えば、どのクラスのデータなのかが分かっていれば、どんなパラメータを持っているかが分かります。
「”祁答院”っていう名前のデータがあるけど、これはなんなんだろう?建物?住所?」
「”祁答院”はユーザークラスのデータらしいぞ」
「なるほど、ということは、祁答院さんはメールアドレスを持っているよね?」
こういう推論が成立するわけです。
「オブジェクト」
きちんとクラスの構造に基づいて作成されたデータを「オブジェクト(時と場合によりインスタンス)」と呼びます。
「ユーザーオブジェクトは、名前というパラメータを持っていて、メールアドレスというパラメータを持っている。」
こういった情報がクラスによって保証されているので、オブジェクトに対してであれば、プログラムがデータを扱う際の手続きをずいぶんと省略することができます。情報を手軽に取り出したり書き込んだりできますし、変な構造のデータを入れる心配もありません。
オブジェクト指向の「オブジェクト」とは、まさにこうしたプログラムが扱いやすい単位でデータをまとめることなのです。
これを基にコードを読むと…?
以上、オブジェクト指向における3つの要素の解説でした。
では、こうした「オブジェクト」「クラス」「パラメータ」に基づいて、冒頭で提示したEloquentのコードの内容をもう一度見てみましょう。
User::withCount([‘orders‘ => function($query) {
$query->whereHave(‘count‘, ‘>’, 0);
}])
->where(‘age‘, ‘>’, 18)
->having(‘orders_count‘, ‘>’, 0)
->orderBy(‘orders_count‘, ‘desc’)
->get([‘name‘, ‘email‘, ‘orders_count‘]);
緑文字がクラス名を示しており、オレンジ文字がパラメータを示しています。
なんとなく、書いてある内容が分かるような気がしてきませんか?
以上、Eloquentとデータベースから入る、「オブジェクト指向」入門でした。
次回から、データベースに関する話から飛び出して、Webシステム全体の話に移ります。
WEB制作・ITに関するお悩みや
ご質問等お気軽にご相談ください