Laravel 8.x データベース:準備

イントロダクション

最近のほとんどすべてのWebアプリケーションは、データベースとやり取りします。Laravelでは、素のSQL、fluent(流暢な)クエリビルダ、およびEloquent ORMを使用して、サポートしているさまざまなでデータベースとのやり取りを非常に簡単にしています。現在、Laravelは5つのデータベースをファーストパーティサポートしています。

設定

Laravelのデータベースサービスの設定は、アプリケーションのconfig/database.php設定ファイルにあります。このファイルは、全データベース接続を定義し、デフォルトで使用する接続を指定できます。このファイル内のほとんどの設定オプションは、アプリケーションの環境変数の値によって決まります。Laravelがサポートしているデータベースシステムのほとんどの設定例をこのファイルに用意しています。

デフォルトのLaravelのサンプル環境設定は、Laravel Sailで使用できるようになっています。SailはローカルマシンでLaravelアプリケーションを開発するためのDocker環境です。しかし、ローカルデータベースの必要に応じ、データベース設定を自由に変更してください。

SQLite設定

SQLiteデータベースは、ファイルシステム上の単一ファイルに含まれます。ターミナルでtouchコマンドを使用して新しいSQLiteデータベースを作成できます。(touch database/database.sqlite)データベースを作成したあと、データベースへの絶対パスをDB_DATABASE環境変数で指定することにより、このデータベースを使用するよう簡単に設定できます。

DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite

SQLite接続の外部キー制約を有効にするには、DB_FOREIGN_KEYS環境変数をtrueに設定する必要があります。

DB_FOREIGN_KEYS=true

Microsoft SQLサーバ設定

Microsoft SQL Serverデータベースを使用するには、sqlsrvpdo_sqlsrvPHP拡張機能と、Microsoft SQL ODBCドライバーなど必要な依存関係パッケージを確実にインストールしてください。

URLを使用した設定

通常、データベース接続は、hostdatabaseusernamepasswordなどの複数の設定値により構成します。こうした設定値には、それぞれ対応する環境変数があります。これは、運用サーバでデータベース接続情報を設定するときに、複数の環境変数を管理する必要があることを意味します。

AWSやHerokuなどの一部のマネージドデータベースプロバイダは、データベースのすべての接続情報を単一の文字カラムで含む単一のデータベース「URL」を提供しています。データベースURLの例は、次のようになります。

mysql://root:password@127.0.0.1/forge?charset=UTF-8

こうしたURLは通常、標準のスキーマ規約に従います。

driver://username:password@host:port/database?options

利便性のため、Laravelは複数の設定オプションを使用してデータベースを構成する代わりに、こうしたURLをサポートしています。url(または対応するDATABASE_URL環境変数)設定オプションが存在する場合は、データベース接続と接続情報を抽出するためにそれを使用します。

読み/書き接続

SELECTステートメントに1つのデータベース接続を使用し、INSERT、UPDATE、およびDELETEステートメントに別のデータベース接続を使用したい場合があるでしょう。Laravelでは簡単に、素のクエリ、クエリビルダ、もしくはEloquent ORMのいずれを使用していても常に適切な接続が使用されます。

読み取り/書き込み接続を設定する方法を確認するため、以下の例を見てみましょう。

'mysql' => [
    'read' => [
        'host' => [
            '192.168.1.1',
            '196.168.1.2',
        ],
    ],
    'write' => [
        'host' => [
            '196.168.1.3',
        ],
    ],
    'sticky' => true,
    'driver' => 'mysql',
    'database' => 'database',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
],

設定配列には、readwritestickyの3キーが追加されていることに注目してください。readキーとwriteキーには、単一のキーとしてhostを含む配列値があります。readおよびwrite接続の残りのデータベースオプションは、メインのmysql設定配列からマージされます。

メインのmysql配列の値をオーバーライドする場合にのみ、read配列とwrite配列へ項目を配置する必要があります。したがって、この場合、192.168.1.1は「読み取り」接続のホストとして使用し、192.168.1.3は「書き込み」接続に使用します。データベースの接続情報、プレフィックス、文字セット、およびメインのmysql配列内の他のすべてのオプションは、両方の接続で共有されます。host設定配列に複数の値が存在する場合、リクエストごとランダムにデータベースホストを選択します。

stickyオプション

stickyオプションは、現在のリクエストサイクル中にデータベースへ書き込まれたレコードをすぐに読み取るため使用するオプション値です。stickyオプションが有効になっており、現在のリクエストサイクル中にデータベースへ対し「書き込み」操作が実行された場合、それ以降の「読み取り」操作では「書き込み」接続が使用されます。これにより、要求サイクル中に書き込まれたデータを、同じ要求中にデータベースからすぐに読み戻すことができます。これがアプリケーションにとって望ましい動作であるかどうかを判断するのは使用者の皆さん次第です。

SQLクエリの実行

データベース接続を設定したら、DBファサードを使用してクエリが実行できます。DBファサードは、クエリのタイプごとにselectupdateinsertdeletestatementメソッドを提供しています。

SELECTクエリの実行

基本的なSELECTクエリを実行するには、DBファサードでselectメソッドを使用します。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;

class UserController extends Controller
{
    /**
     * アプリケーションの全ユーザーのリストを表示
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = DB::select('select * from users where active = ?', [1]);

        return view('user.index', ['users' => $users]);
    }
}

selectメソッドの最初の引数はSQLクエリであり、2番目の引数はクエリにバインドする必要のあるパラメータバインディングです。通常、これらは where句の制約の値です。パラメータバインディングは、SQLインジェクションに対する保護を提供します。

selectメソッドは常に結果の配列を返します。配列内の各結果は、データベースのレコードを表すPHPのstdClassオブジェクトになります。

use Illuminate\Support\Facades\DB;

$users = DB::select('select * from users');

foreach ($users as $user) {
    echo $user->name;
}

名前付きバインディングの使用

パラメータバインディングを表すために?を使用する代わりに、名前付きバインディングを使用してクエリを実行できます。

$results = DB::select('select * from users where id = :id', ['id' => 1]);

INSERT文の実行

insertステートメントを実行するには、DBファサードでinsertメソッドを使用します。selectと同様に、このメソッドはSQLクエリを最初の引数に取り、バインディングを2番目の引数に取ります。

use Illuminate\Support\Facades\DB;

DB::insert('insert into users (id, name) values (?, ?)', [1, 'Marc']);

更新文の実行

データベース内の既存のレコードを更新するには、updateメソッドを使用する必要があります。メソッドは実行の影響を受けた行数を返します。

use Illuminate\Support\Facades\DB;

$affected = DB::update(
    'update users set votes = 100 where name = ?',
    ['Anita']
);

DELETE文の実行

データベースからレコードを削除するには、deleteメソッドを使用する必要があります。updateと同様に、メソッドは影響を受けた行数を返します。

use Illuminate\Support\Facades\DB;

$deleted = DB::delete('delete from users');

一般的な文の実行

一部のデータベース操作文は値を返しません。こうしたタイプの操作では、DBファサードでstatementメソッドを使用します。

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

プリペアドではない文の実行

値をバインドせずSQL文を実行したい場合があります。それには、DBファサードのunpreparedメソッドを使用します。

DB::unprepared('update users set votes = 100 where name = "Dries"');

Note: プリペアドではない文はパラメーターをバインドしないため、SQLインジェクションに対して脆弱である可能性があります。プリペアドではない文内では、ユーザーの値のコントロールを許可しないでください。

暗黙のコミット

トランザクション内でDBファサードのstatementおよびunpreparedメソッドを使用する場合、暗黙のコミットを引き起こすステートメントを回避するように注意する必要があります。これらのステートメントにより、データベースエンジンはトランザクション全体を間接的にコミットし、Laravelはデータベースのトランザクションレベルを認識しなくなります。このようなステートメントの例は、データベーステーブルの作成です。

DB::unprepared('create table a (col varchar(1) null)');

暗黙的なコミットを引き起こす、すべてのステートメントのリストは、MySQLのマニュアルを参照してください。

複数データベース接続の使用

アプリケーションがconfig/database.php設定ファイルで複数の接続を定義している場合、DBファサードが提供するconnectionメソッドを介して各接続にアクセスできます。connectionメソッドに渡される接続名は、config/database.php設定ファイルにリストしている接続、または実行時にconfigヘルパを使用して設定した接続の1つに対応している必要があります。

use Illuminate\Support\Facades\DB;

$users = DB::connection('sqlite')->select(...);

接続インスタンスでgetPdoメソッドを使用して、接続の基になる素のPDOインスタンスにアクセスできます。

$pdo = DB::connection()->getPdo();

クエリイベントのリッスン

アプリケーションが実行するSQLクエリごとに呼び出すクロージャを指定する場合は、DBファサードのlistenメソッドを使用します。このメソッドは、クエリのログ記録やデバッグに役立ちます。クエリリスナクロージャは、サービスプロバイダbootメソッドで登録します。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * アプリケーションの全サービスの登録
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * アプリケーションの全サービスの起動初期処理
     *
     * @return void
     */
    public function boot()
    {
        DB::listen(function ($query) {
            // $query->sql;
            // $query->bindings;
            // $query->time;
        });
    }
}

データベーストランザクション

DBファサードが提供するtransactionメソッドを使用して、データベーストランザクション内で一連の操作を実行できます。トランザクションクロージャ内で例外が投げられた場合、トランザクションを自動的にロールバックし、その例外を再度投げます。クロージャが正常に実行されると、トランザクションを自動的にコミットします。transactionメソッドの使用中にロールバックやコミットを手動で実行する心配はありません。

use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    DB::update('update users set votes = 1');

    DB::delete('delete from posts');
});

デッドロックの処理

transactionメソッドは、デッドロックが発生したときにトランザクションを再試行する回数をオプションとして、2番目の引数に取ります。試行回数が終了した場合は、例外を投げます。

use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    DB::update('update users set votes = 1');

    DB::delete('delete from posts');
}, 5);

トランザクションを手動で使用

トランザクションを手動で開始し、ロールバックとコミットを自分で完全にコントロールしたい場合は、DBファサードが提供するbeginTransactionメソッドを使用します。

use Illuminate\Support\Facades\DB;

DB::beginTransaction();

rollBackメソッドにより、トランザクションをロールバックできます。

DB::rollBack();

commitメソッドにより、トランザクションをコミットできます。

DB::commit();

Tip!! DBファサードのトランザクションメソッドは、クエリビルダEloquent ORMの両方のトランザクションを制御します。

データベースCLIへの接続

データベースのCLIに接続する場合は、db Artisanコマンドを使用します。

php artisan db

必要に応じて、データベース接続名を指定して、デフォルト接続以外のデータベースへ接続できます。

php artisan db mysql

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる