【Laravel】データベース操作:DBファサードによるSQLの実行

2023.10.31 /

【Laravel】データベース操作:DBファサードによるSQLの実行

記事ではLaravelデータベース操作における、DBファサードによるSQLの実行について詳しく解説していきます。

Laravelでデータベース操作をする方法の一つとして「DBファサード(SQLクエリ)」があります。この方法ではSQLクエリを直接記述してデータベースにアクセスします。

本記事を通して、LaravelでのDBファーサード(SQLクエリ)によるデータベース操作について理解を深めてください。

Laravelにおけるデータベース操作

データベース操作をする方法

Laravelでデータベース操作をする方法として以下3つが主要な方法です。

Laravelでデータベース操作をする方法
  • DBファサード(SQLクエリ)
  • DBファサード(クエリビルダ)
  • Eloquent(エロクアント)

本記事ではDBファサードのSQLクエリについて解説していきます。

ファサード(Facades)とは

ファサードとはクラスをインスタンス化しなくてもメソッドを実行できる機能です。

よく利用されるファサードとしてルーティングのweb.phpではRouteファサード、データベース操作で利用するDBファサード、Authファサードなどがあります。

これらのファサードはconfig/app.phpのaliasesで定義されています。

ちなみにEloquentとはLaravelに備わっているORMです。Eloquentによってテーブルをクラスとして定義して、レコードをクラスのインスタンスとして扱うことができます。LaravelのモデルはEloquentの「テーブルをクラスとして定義」する部分を担っています。

Laravel用語の確認

ORMとはデータベースとマッピングされたオブジェクトを利用して、データベースを操作する技法のことです。ORMを利用することで、SQLを意識せずにデータベース上のデータを管理することができます。

Eloquent ORMのモデルを利用することでデータベース操作が容易になり、コードの読み書きが簡単になります。便利なEloquentですが次のようなデメリットがあります。

Eloquentのデメリット
  • 実行されるSQLがわかりづらい、SQLのカスタマイズが難しい
  • 結合するとモデルとテーブルの関係性が壊れる
  • 件数が増えると遅くなる

レコード件数が多い場合や、複数のテーブルを結合する操作ではEloquentの利用はふさわしくないです。このような場面ではDBファサードからクエリビルダを利用することが望ましいです。

DBファサード

DBファサードとは

DBファサードとはデータベース操作に必要な機能をまとめたクラスのファサードです。Illuminate\Support\Facadesに用意されているファサードであり、クラス名は「DB」です。DBクラスには様々なメソッドが備わっており、メソッドを呼び出してデータベース操作を行います。

DBファサードでは「クエリビルダ」という機能が備わっており、メソッドチェーンを使って最適化したクエリを実行できます。

POINT

Eloquentでは避けるべき大きなデータセットを操作する際にDBファサードが活躍します

DBクラスは以下構文に沿って利用します。

構文

$変数 = DB::メソッド

注意点

クエリビルダを使わずにDBファザードでSQLを実行する場合は若干柔軟性に欠けます。またユーザーからの値をSQLに埋め込むなどの場合は「SQLインジェクション攻撃」などの対応も考える必要があります

DBファサードの使用方法

DBファサードをuseする

DBファサードを利用する場合、必ずスクリプトにDBファサードをuse文で読み込んでおきます。

use Illuminate\Support\Facades\DB;

データ(レコード)の取得:select()

DBクラスにあるselect()メソッドを使用することで引数に指定したSQL文を実行します。

構文

$変数 = DB::select(SQL文);

引数に指定したSQL文を実行してデータベースからレコードを取得します。SQL文には基本的にはselect文を指定して、レコードの取得に用います。

select()メソッドの戻り値はレコード値の配列となっています。テンプレートでは以下のように記述します。

// コントローラー BlogController.php
<?php

namespace App\Http\Controllers;

use App\Models\Blog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class BlogController extends Controller
{
    public function index(Request $request)
    {
        $items = DB::select('select * from blogs');
        return view('welcome', ['items' => $items]);
    }
}
// welcome.blade.php
<table>
    <tr>
        <th>ID</th>
        <th>タイトル</th>
        <th>コンテンツ</th>
    </tr>
    @foreach ($items as $item)
        <tr>
            <td>{{$item->id}}</td>
            <td>{{$item->title}}</td>
            <td>{{$item->contents}}</td>
        </tr>
    @endforeach
</table>

パラメータ結合によるSQL文の作成

select文の第二引数に配列を指定することで配列の値がSQL文の指定した箇所に埋め込まれる「パラメータ結合」という機能があります。

例えば次のように配列を埋め込みたい箇所に「?」を入れることで、配列の値が順次埋め込まれていきます。

$items = DB::select('select * from blogs where id = ? and email = ?', [54, 'office54@office54.net']);

またはプレースホルダを使ってパラメータを埋め込むことができます。この際は配列は連想配列で用意して、連想配列のキーと同じプレースホルダに値が埋め込まれます。

$params = ['id' => 54, 'email' => 'office54@office54.net'];
$items = DB::select('select * from blogs where id = :id and email = :email', $params);
POINT

このように引数で渡すことでSQLインジェクションを防ぐことができます。積極的に利用するようにしてください。

データ(レコード)の追加:insert()

DBクラスにあるinsert()メソッドを使用することでレコードを追加するSQL文を実行します。

構文

DB::insert(SQL文);

引数に指定したinsert文を実行します。第二引数にパラメータを指定して利用することもできます。

$params = ['title' => 'test', 'contents' => 'I have a dream.'];
DB::insert('insert into blogs (title, contents) values (:title, :contents)', $params);

データ(レコード)の更新:update

DBクラスにあるupdate()メソッドを使用することでレコードを更新するSQL文を実行します。

構文

DB::update(SQL文);

引数に指定したupdate文を実行します。第二引数にパラメータを指定して利用することもできます。

$params = ['title' => $request->title, 'contents' => $request->contents, 'id' => request->id];
DB::update('update blogs set title = :title, contents = :contents where id = :id', $params);

データ(レコード)の削除:delete()

DBクラスにあるdelete()メソッドを使用することでレコードを削除するSQL文を実行します。

構文

DB::delete(SQL文);

引数に指定したdelete文を実行します。第二引数にパラメータを指定して利用することもできます。

$params = ['id' => request->id];
DB::delete('delete from blogs where id = :id', $params);

SQLをそのまま実行:raw()

DBクラスにあるraw()メソッドを使用することで指定したSQL文をそのまま実行します。

構文

$変数 = DB::raw(SQL文);

raw()はSQLクエリ全般を実行します。SQL関数やCASE文などを利用したい場合に使います。

値を返さないSQL文を実行:statement()

DBクラスにあるstatement()メソッドは値を返さないSQL文の実行で利用します。

構文

DB::statement(SQL文)

例えばdrop文の実行やデータベースでビューの作成などで利用できます。

DB::statement('drop table blogs');